From 9d2b137d9d15b2c214b7e4c2e979d26df94e930c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rn=20=C3=98lmheim?= Date: Tue, 14 Aug 2012 13:33:54 +0200 Subject: [PATCH 1/6] Added debug statements and fix for 0.12.3 bug --- tracsubtickets/api.py | 6 +++--- tracsubtickets/web_ui.py | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tracsubtickets/api.py b/tracsubtickets/api.py index 35fbed7..df20453 100644 --- a/tracsubtickets/api.py +++ b/tracsubtickets/api.py @@ -147,7 +147,7 @@ def ticket_changed(self, ticket, comment, author, old_values): # remove old parents for parent in old_parents - new_parents: - cursor.execute("DELETE FROM subtickets WHERE parent=%s AND child=%s", + cursor.execute("DELETE FROM subtickets WHERE parent='%s' AND child='%s'", (parent, ticket.id)) # add new parents for parent in new_parents - old_parents: @@ -159,7 +159,7 @@ def ticket_deleted(self, ticket): db = self.env.get_db_cnx() cursor = db.cursor() # TODO: check if there's any child ticket - cursor.execute("DELETE FROM subtickets WHERE child=%s", (ticket.id, )) + cursor.execute("DELETE FROM subtickets WHERE child='%s'", (ticket.id, )) db.commit() # ITicketManipulator methods @@ -189,7 +189,7 @@ def validate_ticket(self, req, ticket): def _check_parents(id, all_parents): all_parents = all_parents + [id] errors = [] - cursor.execute("SELECT parent FROM subtickets WHERE child=%s", (id, )) + cursor.execute("SELECT parent FROM subtickets WHERE child='%s'", (id, )) for x in [int(x[0]) for x in cursor]: if x in all_parents: error = ' > '.join(['#%s' % n for n in all_parents + [x]]) diff --git a/tracsubtickets/web_ui.py b/tracsubtickets/web_ui.py index 3b33175..32bdc2e 100644 --- a/tracsubtickets/web_ui.py +++ b/tracsubtickets/web_ui.py @@ -98,10 +98,11 @@ def get_children(self, parent_id, db=None): if not db: db = self.env.get_db_cnx() cursor = db.cursor() - cursor.execute("SELECT parent, child FROM subtickets WHERE parent=%s", + cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", (parent_id, )) for parent, child in cursor: + printf('Parent: %s has child: %s', parent, child) children[child] = None for id in children: @@ -115,7 +116,7 @@ def validate_ticket(self, req, ticket): db = self.env.get_db_cnx() cursor = db.cursor() - cursor.execute("SELECT parent, child FROM subtickets WHERE parent=%s", + cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", (ticket.id, )) for parent, child in cursor: @@ -146,7 +147,8 @@ def filter_stream(self, req, method, filename, stream, data): link = None div.append(tag.h3(_('Subtickets '), link)) - if 'subtickets' in data: + if 'subtickets' in data:i + printf("Subtickets in data") # table tbody = tag.tbody() div.append(tag.table(tbody, class_='subtickets')) From 5ba7c049cb1da919af7b923f2f7455e739c03162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=F8rn=20=D8lmheim?= Date: Wed, 15 Aug 2012 12:59:26 +0200 Subject: [PATCH 2/6] Updated all sql statements to new way of binding to variables. --- tracsubtickets/api.py | 24 +++++++++++------------- tracsubtickets/web_ui.py | 14 ++++---------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/tracsubtickets/api.py b/tracsubtickets/api.py index df20453..df8522c 100644 --- a/tracsubtickets/api.py +++ b/tracsubtickets/api.py @@ -47,7 +47,7 @@ # i18n support for plugins, available since Trac r7705 # use _, tag_ and N_ as usual, e.g. _("this is a message text") -_, tag_, N_, add_domain = domain_functions('tracsubtickets', +_, tag_, N_, add_domain = domain_functions('tracsubtickets', '_', 'tag_', 'N_', 'add_domain') @@ -71,7 +71,7 @@ def environment_created(self): def environment_needs_upgrade(self, db): cursor = db.cursor() - cursor.execute("SELECT value FROM system WHERE name=%s", + cursor.execute("SELECT value FROM system WHERE name=%s" % \ (db_default.name, )) value = cursor.fetchone() try: @@ -95,17 +95,17 @@ def upgrade_environment(self, db): old_data = {} # {table.name: (cols, rows)} cursor = db.cursor() if not self.found_db_version: - cursor.execute("INSERT INTO system (name, value) VALUES (%s, %s)", + cursor.execute("INSERT INTO system (name, value) VALUES (%s, %s)" %\ (db_default.name, db_default.version)) else: - cursor.execute("UPDATE system SET value=%s WHERE name=%s", + cursor.execute("UPDATE system SET value=%s WHERE name=%s" % \ (db_default.version, db_default.name)) for table in db_default.tables: - cursor.execute("SELECT * FROM %s", (table.name, )) + cursor.execute("SELECT * FROM %s" % (table.name, )) cols = [x[0] for x in cursor.description], rows = cursor.fetchall() old_data[table.name] = (cols, rows) - cursor.execute("DROP TABLE %s", (table.name)) + cursor.execute("DROP TABLE %s" % (table.name)) # insert the default table for table in db_default.tables: @@ -147,19 +147,17 @@ def ticket_changed(self, ticket, comment, author, old_values): # remove old parents for parent in old_parents - new_parents: - cursor.execute("DELETE FROM subtickets WHERE parent='%s' AND child='%s'", - (parent, ticket.id)) + cursor.execute("DELETE FROM subtickets WHERE parent='%s' AND child='%s'" % (parent, ticket.id)) # add new parents for parent in new_parents - old_parents: - cursor.execute("INSERT INTO subtickets VALUES(%s, %s)", - (parent, ticket.id)) + cursor.execute("INSERT INTO subtickets VALUES(%s, %s)" % (parent, ticket.id)) db.commit() def ticket_deleted(self, ticket): db = self.env.get_db_cnx() cursor = db.cursor() # TODO: check if there's any child ticket - cursor.execute("DELETE FROM subtickets WHERE child='%s'", (ticket.id, )) + cursor.execute("DELETE FROM subtickets WHERE child='%s'" % ticket.id) db.commit() # ITicketManipulator methods @@ -179,7 +177,7 @@ def validate_ticket(self, req, ticket): yield 'parents', _('A ticket cannot be a parent to itself') else: # check if the id exists - cursor.execute("SELECT id FROM ticket WHERE id=%s", (id, )) + cursor.execute("SELECT id FROM ticket WHERE id=%s" % id) row = cursor.fetchone() if row is None: yield 'parents', _('Ticket #%s does not exist') % id @@ -189,7 +187,7 @@ def validate_ticket(self, req, ticket): def _check_parents(id, all_parents): all_parents = all_parents + [id] errors = [] - cursor.execute("SELECT parent FROM subtickets WHERE child='%s'", (id, )) + cursor.execute("SELECT parent FROM subtickets WHERE child='%s'" % id) for x in [int(x[0]) for x in cursor]: if x in all_parents: error = ' > '.join(['#%s' % n for n in all_parents + [x]]) diff --git a/tracsubtickets/web_ui.py b/tracsubtickets/web_ui.py index 32bdc2e..9f70d1e 100644 --- a/tracsubtickets/web_ui.py +++ b/tracsubtickets/web_ui.py @@ -98,26 +98,21 @@ def get_children(self, parent_id, db=None): if not db: db = self.env.get_db_cnx() cursor = db.cursor() - cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", - (parent_id, )) - + cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'" % parent_id) for parent, child in cursor: - printf('Parent: %s has child: %s', parent, child) children[child] = None for id in children: children[id] = self.get_children(id, db) return children - + def validate_ticket(self, req, ticket): action = req.args.get('action') if action == 'resolve': db = self.env.get_db_cnx() cursor = db.cursor() - - cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", - (ticket.id, )) + cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'" % ticket.id) for parent, child in cursor: if Ticket(self.env, child)['status'] != 'closed': @@ -147,8 +142,7 @@ def filter_stream(self, req, method, filename, stream, data): link = None div.append(tag.h3(_('Subtickets '), link)) - if 'subtickets' in data:i - printf("Subtickets in data") + if 'subtickets' in data: # table tbody = tag.tbody() div.append(tag.table(tbody, class_='subtickets')) From 8151ed89e3de3c32f3913ecf8ea0f731132ae054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=F8rn=20=D8lmheim?= Date: Thu, 16 Aug 2012 11:06:01 +0200 Subject: [PATCH 3/6] Added debug statements --- tracsubtickets/api.py | 29 ++++++++++++++--------------- tracsubtickets/web_ui.py | 11 ++++++----- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tracsubtickets/api.py b/tracsubtickets/api.py index df8522c..e1bb308 100644 --- a/tracsubtickets/api.py +++ b/tracsubtickets/api.py @@ -71,8 +71,7 @@ def environment_created(self): def environment_needs_upgrade(self, db): cursor = db.cursor() - cursor.execute("SELECT value FROM system WHERE name=%s" % \ - (db_default.name, )) + cursor.execute("SELECT value FROM system WHERE name=%s", (db_default.name, )) value = cursor.fetchone() try: self.found_db_version = int(value[0]) @@ -95,17 +94,15 @@ def upgrade_environment(self, db): old_data = {} # {table.name: (cols, rows)} cursor = db.cursor() if not self.found_db_version: - cursor.execute("INSERT INTO system (name, value) VALUES (%s, %s)" %\ - (db_default.name, db_default.version)) + cursor.execute("INSERT INTO system (name, value) VALUES (%s, %s)", (db_default.name, db_default.version)) else: - cursor.execute("UPDATE system SET value=%s WHERE name=%s" % \ - (db_default.version, db_default.name)) + cursor.execute("UPDATE system SET value=%s WHERE name=%s", (db_default.version, db_default.name)) for table in db_default.tables: - cursor.execute("SELECT * FROM %s" % (table.name, )) + cursor.execute("SELECT * FROM %s", (table.name, )) cols = [x[0] for x in cursor.description], rows = cursor.fetchall() old_data[table.name] = (cols, rows) - cursor.execute("DROP TABLE %s" % (table.name)) + cursor.execute("DROP TABLE %s", (table.name, )) # insert the default table for table in db_default.tables: @@ -132,32 +129,34 @@ def ticket_created(self, ticket): self.ticket_changed(ticket, '', ticket['reporter'], {'parents': ''}) def ticket_changed(self, ticket, comment, author, old_values): + self.log.debug("Ticket changed. Ticket id: %s" % ticket.id) if 'parents' not in old_values: return old_parents = old_values.get('parents', '') or '' old_parents = set(NUMBERS_RE.findall(old_parents)) new_parents = set(NUMBERS_RE.findall(ticket['parents'] or '')) - + self.log.debug("Old parents: %s" % old_parents) + self.log.debug("New parents: %s" % new_parents) if new_parents == old_parents: return db = self.env.get_db_cnx() cursor = db.cursor() - + self.log.debug("Old parents should be removed.") # remove old parents for parent in old_parents - new_parents: - cursor.execute("DELETE FROM subtickets WHERE parent='%s' AND child='%s'" % (parent, ticket.id)) + cursor.execute("DELETE FROM subtickets WHERE parent='%s' AND child='%s'", (parent, ticket.id)) # add new parents for parent in new_parents - old_parents: - cursor.execute("INSERT INTO subtickets VALUES(%s, %s)" % (parent, ticket.id)) + cursor.execute("INSERT INTO subtickets VALUES(%s, %s)", (parent, ticket.id)) db.commit() def ticket_deleted(self, ticket): db = self.env.get_db_cnx() cursor = db.cursor() # TODO: check if there's any child ticket - cursor.execute("DELETE FROM subtickets WHERE child='%s'" % ticket.id) + cursor.execute("DELETE FROM subtickets WHERE child='%s'", (ticket.id, )) db.commit() # ITicketManipulator methods @@ -177,7 +176,7 @@ def validate_ticket(self, req, ticket): yield 'parents', _('A ticket cannot be a parent to itself') else: # check if the id exists - cursor.execute("SELECT id FROM ticket WHERE id=%s" % id) + cursor.execute("SELECT id FROM ticket WHERE id=%s", (id, )) row = cursor.fetchone() if row is None: yield 'parents', _('Ticket #%s does not exist') % id @@ -187,7 +186,7 @@ def validate_ticket(self, req, ticket): def _check_parents(id, all_parents): all_parents = all_parents + [id] errors = [] - cursor.execute("SELECT parent FROM subtickets WHERE child='%s'" % id) + cursor.execute("SELECT parent FROM subtickets WHERE child='%s'", (id, )) for x in [int(x[0]) for x in cursor]: if x in all_parents: error = ' > '.join(['#%s' % n for n in all_parents + [x]]) diff --git a/tracsubtickets/web_ui.py b/tracsubtickets/web_ui.py index 9f70d1e..efb2e86 100644 --- a/tracsubtickets/web_ui.py +++ b/tracsubtickets/web_ui.py @@ -37,9 +37,7 @@ from api import NUMBERS_RE, _ - class SubTicketsModule(Component): - implements(ITemplateProvider, IRequestFilter, ITicketManipulator, @@ -94,12 +92,15 @@ def prepare_ticket(self, req, ticket, fields, actions): pass def get_children(self, parent_id, db=None): + self.log.debug("Get children for parent: %s" % parent_id) children = {} if not db: db = self.env.get_db_cnx() cursor = db.cursor() - cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'" % parent_id) + self.log.debug("SELECT parent, child FROM subtickets WHERE parent='%s'" % parent_id) + cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", [parent_id]) for parent, child in cursor: + self.log.debug("Parent %s has child %s" % (parent, child)) children[child] = None for id in children: @@ -112,7 +113,7 @@ def validate_ticket(self, req, ticket): if action == 'resolve': db = self.env.get_db_cnx() cursor = db.cursor() - cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'" % ticket.id) + cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", (ticket.id, )) for parent, child in cursor: if Ticket(self.env, child)['status'] != 'closed': @@ -123,7 +124,7 @@ def validate_ticket(self, req, ticket): for id in ids: if Ticket(self.env, id)['status'] == 'closed': yield None, _('Parent ticket #%s is closed') % id - + env.log.debug("Valid ticket with subtickets.") # ITemplateStreamFilter method def filter_stream(self, req, method, filename, stream, data): if req.path_info.startswith('/ticket/'): From 247ba2017dd0ae02e8f1e3ca54ff76d39644d4ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=F8rn=20=D8lmheim?= Date: Thu, 16 Aug 2012 14:27:38 +0200 Subject: [PATCH 4/6] Changed the way ids are converted from numbers to strings. --- tracsubtickets/api.py | 5 +++-- tracsubtickets/web_ui.py | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tracsubtickets/api.py b/tracsubtickets/api.py index e1bb308..47bcba2 100644 --- a/tracsubtickets/api.py +++ b/tracsubtickets/api.py @@ -143,10 +143,11 @@ def ticket_changed(self, ticket, comment, author, old_values): db = self.env.get_db_cnx() cursor = db.cursor() - self.log.debug("Old parents should be removed.") + # remove old parents for parent in old_parents - new_parents: - cursor.execute("DELETE FROM subtickets WHERE parent='%s' AND child='%s'", (parent, ticket.id)) + cursor.execute("DELETE FROM subtickets WHERE parent = %s AND child = %s", [str(parent), str(ticket.id)] ) + # add new parents for parent in new_parents - old_parents: cursor.execute("INSERT INTO subtickets VALUES(%s, %s)", (parent, ticket.id)) diff --git a/tracsubtickets/web_ui.py b/tracsubtickets/web_ui.py index efb2e86..706ac96 100644 --- a/tracsubtickets/web_ui.py +++ b/tracsubtickets/web_ui.py @@ -96,11 +96,11 @@ def get_children(self, parent_id, db=None): children = {} if not db: db = self.env.get_db_cnx() + cursor = db.cursor() - self.log.debug("SELECT parent, child FROM subtickets WHERE parent='%s'" % parent_id) - cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", [parent_id]) + cursor.execute("SELECT parent, child FROM subtickets WHERE parent = %s", [str(parent_id)] ) + for parent, child in cursor: - self.log.debug("Parent %s has child %s" % (parent, child)) children[child] = None for id in children: @@ -124,7 +124,7 @@ def validate_ticket(self, req, ticket): for id in ids: if Ticket(self.env, id)['status'] == 'closed': yield None, _('Parent ticket #%s is closed') % id - env.log.debug("Valid ticket with subtickets.") + # ITemplateStreamFilter method def filter_stream(self, req, method, filename, stream, data): if req.path_info.startswith('/ticket/'): From 068fd4fdc9387abae5f80e011a9510ac4ceeefba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=F8rn=20=D8lmheim?= Date: Thu, 16 Aug 2012 14:53:40 +0200 Subject: [PATCH 5/6] Added the fix to the validation as well. --- tracsubtickets/web_ui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracsubtickets/web_ui.py b/tracsubtickets/web_ui.py index 706ac96..968398c 100644 --- a/tracsubtickets/web_ui.py +++ b/tracsubtickets/web_ui.py @@ -98,7 +98,7 @@ def get_children(self, parent_id, db=None): db = self.env.get_db_cnx() cursor = db.cursor() - cursor.execute("SELECT parent, child FROM subtickets WHERE parent = %s", [str(parent_id)] ) + cursor.execute("SELECT parent, child FROM subtickets WHERE parent=%s", [str(parent_id)] ) for parent, child in cursor: children[child] = None @@ -113,7 +113,7 @@ def validate_ticket(self, req, ticket): if action == 'resolve': db = self.env.get_db_cnx() cursor = db.cursor() - cursor.execute("SELECT parent, child FROM subtickets WHERE parent='%s'", (ticket.id, )) + cursor.execute("SELECT parent, child FROM subtickets WHERE parent=%s", [str(ticket.id)] ) for parent, child in cursor: if Ticket(self.env, child)['status'] != 'closed': From 98d61ee7139c8802acdf1f268ce840c7325dac14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=F8rn=20=D8lmheim?= Date: Thu, 16 Aug 2012 14:57:07 +0200 Subject: [PATCH 6/6] Added the fix to the some more of the api methods. --- tracsubtickets/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracsubtickets/api.py b/tracsubtickets/api.py index 47bcba2..7818b1f 100644 --- a/tracsubtickets/api.py +++ b/tracsubtickets/api.py @@ -157,7 +157,7 @@ def ticket_deleted(self, ticket): db = self.env.get_db_cnx() cursor = db.cursor() # TODO: check if there's any child ticket - cursor.execute("DELETE FROM subtickets WHERE child='%s'", (ticket.id, )) + cursor.execute("DELETE FROM subtickets WHERE child=%s", [str(ticket.id)]) db.commit() # ITicketManipulator methods @@ -187,7 +187,7 @@ def validate_ticket(self, req, ticket): def _check_parents(id, all_parents): all_parents = all_parents + [id] errors = [] - cursor.execute("SELECT parent FROM subtickets WHERE child='%s'", (id, )) + cursor.execute("SELECT parent FROM subtickets WHERE child=%s", [str(id)]) for x in [int(x[0]) for x in cursor]: if x in all_parents: error = ' > '.join(['#%s' % n for n in all_parents + [x]])