class TracDatabase(object): def __init__(self, path): self.env = Environment(path) self.loginNameCache = {} self.fieldNameCache = {} from trac.db.api import DatabaseManager self.using_postgres = \ DatabaseManager(self.env).connection_uri.startswith("postgres:") def hasTickets(self): return int(self.env.db_query("SELECT count(*) FROM ticket")[0][0] > 0) def assertNoTickets(self): if self.hasTickets(): raise Exception("Will not modify database with existing tickets!") def setSeverityList(self, s): """Remove all severities, set them to `s`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM enum WHERE type='severity'") for value, i in s: print(" inserting severity '%s' - '%s'" % (value, i)) db("""INSERT INTO enum (type, name, value) VALUES (%s, %s, %s)""", ("severity", value, i)) def setPriorityList(self, s): """Remove all priorities, set them to `s`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM enum WHERE type='priority'") for value, i in s: print(" inserting priority '%s' - '%s'" % (value, i)) db("INSERT INTO enum (type, name, value) VALUES (%s, %s, %s)", ("priority", value, i)) def setComponentList(self, l, key): """Remove all components, set them to `l`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM component") for comp in l: print(" inserting component '%s', owner '%s'" % (comp[key], comp['owner'])) db("INSERT INTO component (name, owner) VALUES (%s, %s)", (comp[key], comp['owner'])) def setVersionList(self, v, key): """Remove all versions, set them to `v`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM version") for vers in v: print(" inserting version '%s'" % vers[key]) db("INSERT INTO version (name) VALUES (%s)", (vers[key],)) def setMilestoneList(self, m, key): """Remove all milestones, set them to `m`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM milestone") for ms in m: milestone = ms[key] print(" inserting milestone '%s'" % milestone) db("INSERT INTO milestone (name) VALUES (%s)", (milestone,)) def addTicket(self, id, time, changetime, component, severity, priority, owner, reporter, cc, version, milestone, status, resolution, summary, description, keywords, customfields): desc = description type = "defect" if SEVERITIES: if severity.lower() == "enhancement": severity = "minor" type = "enhancement" else: if priority.lower() == "enhancement": priority = "minor" type = "enhancement" if PREFORMAT_COMMENTS: desc = '{{{\n%s\n}}}' % desc if REPLACE_BUG_NO: if BUG_NO_RE.search(desc): desc = re.sub(BUG_NO_RE, BUG_NO_REPL, desc) if priority in PRIORITIES_MAP: priority = PRIORITIES_MAP[priority] print(" inserting ticket %s -- %s" % (id, summary)) with self.env.db_transaction as db: db("""INSERT INTO ticket (id, type, time, changetime, component, severity, priority, owner, reporter, cc, version, milestone, status, resolution, summary, description, keywords) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """, (id, type, datetime2epoch(time), datetime2epoch(changetime), component, severity, priority, owner, reporter, cc, version, milestone, status.lower(), resolution, summary, desc, keywords)) if self.using_postgres: with self.env.db_transaction as db: c = db.cursor() c.execute(""" SELECT SETVAL('ticket_id_seq', MAX(id)) FROM ticket; SELECT SETVAL('report_id_seq', MAX(id)) FROM report""") ticket_id = db.get_last_id(c, 'ticket') # add all custom fields to ticket for name, value in customfields.iteritems(): self.addTicketCustomField(ticket_id, name, value) return ticket_id def addTicketCustomField(self, ticket_id, field_name, field_value): if field_value is None: return self.env.db_transaction(""" INSERT INTO ticket_custom (ticket, name, value) VALUES (%s, %s, %s) """, (ticket_id, field_name, field_value)) def addTicketComment(self, ticket, time, author, value): comment = value if PREFORMAT_COMMENTS: comment = '{{{\n%s\n}}}' % comment if REPLACE_BUG_NO: if BUG_NO_RE.search(comment): comment = re.sub(BUG_NO_RE, BUG_NO_REPL, comment) with self.env.db_transaction as db: db("""INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s) """, (ticket, datetime2epoch(time), author, 'comment', '', comment)) def addTicketChange(self, ticket, time, author, field, oldvalue, newvalue): if field == "owner": if oldvalue in LOGIN_MAP: oldvalue = LOGIN_MAP[oldvalue] if newvalue in LOGIN_MAP: newvalue = LOGIN_MAP[newvalue] if field == "priority": if oldvalue.lower() in PRIORITIES_MAP: oldvalue = PRIORITIES_MAP[oldvalue.lower()] if newvalue.lower() in PRIORITIES_MAP: newvalue = PRIORITIES_MAP[newvalue.lower()] # Doesn't make sense if we go from highest -> highest, for example. if oldvalue == newvalue: return with self.env.db_transaction as db: db("""INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s) """, (ticket, datetime2epoch(time), author, field, oldvalue, newvalue)) def addAttachment(self, author, a): if a['filename'] != '': description = a['description'] id = a['bug_id'] filename = a['filename'] filedata = io.BytesIO(a['thedata']) filesize = len(filedata.getvalue()) time = a['creation_ts'] print(" ->inserting attachment '%s' for ticket %s -- %s" % (filename, id, description)) attachment = Attachment(self.env, 'ticket', id) attachment.author = author attachment.description = description attachment.insert(filename, filedata, filesize, datetime2epoch(time)) del attachment def getLoginName(self, cursor, userid): if userid not in self.loginNameCache: cursor.execute("SELECT * FROM profiles WHERE userid = %s", userid) loginName = cursor.fetchall() if loginName: loginName = loginName[0]['login_name'] else: print("WARNING: unknown bugzilla userid %d, recording as" " anonymous" % userid) loginName = "anonymous" loginName = LOGIN_MAP.get(loginName, loginName) self.loginNameCache[userid] = loginName return self.loginNameCache[userid] def getFieldName(self, cursor, fieldid): if fieldid not in self.fieldNameCache: # fielddefs.fieldid got changed to fielddefs.id in Bugzilla # 2.23.3. if BZ_VERSION >= 2233: cursor.execute("SELECT * FROM fielddefs WHERE id = %s", fieldid) else: cursor.execute("SELECT * FROM fielddefs WHERE fieldid = %s", fieldid) fieldName = cursor.fetchall() if fieldName: fieldName = fieldName[0]['name'].lower() else: print("WARNING: unknown bugzilla fieldid %d, " " recording as unknown" % fieldid) fieldName = "unknown" self.fieldNameCache[fieldid] = fieldName return self.fieldNameCache[fieldid]
class TracDatabase(object): def __init__(self, path): self.env = Environment(path) self.loginNameCache = {} self.fieldNameCache = {} from trac.db.api import DatabaseManager self.using_postgres = \ DatabaseManager(self.env).connection_uri.startswith("postgres:") def hasTickets(self): return int(self.env.db_query("SELECT count(*) FROM ticket")[0][0] > 0) def assertNoTickets(self): if self.hasTickets(): raise Exception("Will not modify database with existing tickets!") def setSeverityList(self, s): """Remove all severities, set them to `s`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM enum WHERE type='severity'") for value, i in s: #print " inserting severity '%s' - '%s'" % (value, i) db("""INSERT INTO enum (type, name, value) VALUES (%s, %s, %s)""", ("severity", value, i)) def setPriorityList(self, s): """Remove all priorities, set them to `s`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM enum WHERE type='priority'") for value, i in s: print " inserting priority '%s' - '%s'" % (value, i) db("INSERT INTO enum (type, name, value) VALUES (%s, %s, %s)", ("priority", value, i)) def setComponentList(self, l): """Remove all components, set them to `l`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM component") for comp in l: #print " inserting component '%s', owner '%s'" % \ # (comp, DEF_OWNER) db("INSERT INTO component (name, owner) VALUES (%s, %s)", (comp, DEF_OWNER)) def setVersionList(self, v, key): """Remove all versions, set them to `v`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM version") for vers in v: print " inserting version '%s'" % (vers[key]) db("INSERT INTO version (name) VALUES (%s)", (vers[key],)) def setMilestoneList(self, m, key): """Remove all milestones, set them to `m`""" self.assertNoTickets() with self.env.db_transaction as db: db("DELETE FROM milestone") for ms in m: milestone = ms[key] print " inserting milestone '%s'" % (milestone) db("INSERT INTO milestone (name) VALUES (%s)", (milestone,)) def addTicket(self, id, time, changetime, component, severity, priority, owner, reporter, cc, version, milestone, status, resolution, summary, description, keywords, customfields): desc = description type = "defect" if SEVERITIES: if severity.lower() == "enhancement": severity = "minor" type = "enhancement" else: if priority.lower() == "enhancement": priority = "minor" type = "enhancement" if PREFORMAT_COMMENTS: desc = '{{{\n%s\n}}}' % desc if REPLACE_BUG_NO: if BUG_NO_RE.search(desc): desc = re.sub(BUG_NO_RE, BUG_NO_REPL, desc) if PRIORITIES_MAP.has_key(priority): priority = PRIORITIES_MAP[priority] print " inserting ticket %s -- %s" % (id, summary) with self.env.db_transaction as db: db("""INSERT INTO ticket (id, type, time, changetime, component, severity, priority, owner, reporter, cc, version, milestone, status, resolution, summary, description, keywords) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """, (id, type, datetime2epoch(time), datetime2epoch(changetime), component, severity, priority, owner, reporter, cc, version, milestone, status.lower(), resolution, summary, desc, keywords)) if self.using_postgres: with self.env.db_transaction as db: c = db.cursor() c.execute(""" SELECT SETVAL('ticket_id_seq', MAX(id)) FROM ticket; SELECT SETVAL('report_id_seq', MAX(id)) FROM report""") ticket_id = db.get_last_id(c, 'ticket') # add all custom fields to ticket for name, value in customfields.iteritems(): self.addTicketCustomField(ticket_id, name, value) #return ticket_id def addTicketCustomField(self, ticket_id, field_name, field_value): if field_value == None: return self.env.db_transaction(""" INSERT INTO ticket_custom (ticket, name, value) VALUES (%s, %s, %s) """, (ticket_id, field_name, field_value)) def addTicketComment(self, ticket, time, author, value): comment = value if PREFORMAT_COMMENTS: comment = '{{{\n%s\n}}}' % comment if REPLACE_BUG_NO: if BUG_NO_RE.search(comment): comment = re.sub(BUG_NO_RE, BUG_NO_REPL, comment) with self.env.db_transaction as db: db("""INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s) """, (ticket, datetime2epoch(time), author, 'comment', '', comment)) def addTicketChange(self, ticket, time, author, field, oldvalue, newvalue): if field == "owner": if LOGIN_MAP.has_key(oldvalue): oldvalue = LOGIN_MAP[oldvalue] if LOGIN_MAP.has_key(newvalue): newvalue = LOGIN_MAP[newvalue] if field == "priority": if PRIORITIES_MAP.has_key(oldvalue.lower()): oldvalue = PRIORITIES_MAP[oldvalue.lower()] if PRIORITIES_MAP.has_key(newvalue.lower()): newvalue = PRIORITIES_MAP[newvalue.lower()] # Doesn't make sense if we go from highest -> highest, for example. if oldvalue == newvalue: return with self.env.db_transaction as db: db("""INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s) """, (ticket, datetime2epoch(time), author, field, oldvalue, newvalue)) def addAttachment(self, author, a): if a['filename'] != '': description = a['description'].strip() id = a['bug_id'] filename = a['filename'].strip() filedata = StringIO(a['thedata']) filesize = len(filedata.getvalue()) time = a['creation_ts'] #print "author: " + author print "id: %d" % id print "filename: " + filename #print "filesize: %d" % filesize #print "description: " + description #print " ->inserting attachment '%s' for ticket %s -- %s" % \ # (filename, id, description) attachment = Attachment(self.env, 'ticket', id) attachment.author = author attachment.description = description attachment.insert(filename, filedata, filesize, datetime2epoch(time)) #del attachment def getLoginName(self, cursor, userid): if userid not in self.loginNameCache: cursor.execute("SELECT * FROM profiles WHERE userid = %s", (userid)) loginName = cursor.fetchall() if loginName: loginName = loginName[0]['login_name'] else: print """WARNING: unknown bugzilla userid %d, recording as anonymous""" % (userid) loginName = "anonymous" loginName = LOGIN_MAP.get(loginName, loginName) self.loginNameCache[userid] = loginName return self.loginNameCache[userid] def getFieldName(self, cursor, fieldid): if fieldid not in self.fieldNameCache: # fielddefs.fieldid got changed to fielddefs.id in Bugzilla # 2.23.3. if BZ_VERSION >= 2233: cursor.execute("SELECT * FROM fielddefs WHERE id = %s", (fieldid)) else: cursor.execute("SELECT * FROM fielddefs WHERE fieldid = %s", (fieldid)) fieldName = cursor.fetchall() if fieldName: fieldName = fieldName[0]['name'].lower() else: print "WARNING: unknown bugzilla fieldid %d, \ recording as unknown" % (userid) fieldName = "unknown" self.fieldNameCache[fieldid] = fieldName return self.fieldNameCache[fieldid]
class TracDatabase(object): def __init__(self, path): self.env = Environment(path) def hasTickets(self): return int(self.env.db_query("SELECT count(*) FROM ticket")[0][0]) > 0 def dbCheck(self): if self.hasTickets(): raise DBNotEmpty def setTypeList(self, s): """Remove all types, set them to `s`""" self.dbCheck() with self.env.db_transaction as db: db("DELETE FROM enum WHERE type='ticket_type'") for i, value in enumerate(s): db("INSERT INTO enum (type, name, value) VALUES (%s, %s, %s)", ("ticket_type", value, i)) def setPriorityList(self, s): """Remove all priorities, set them to `s`""" self.dbCheck() with self.env.db_transaction as db: db("DELETE FROM enum WHERE type='priority'") for i, value in enumerate(s): db("INSERT INTO enum (type, name, value) VALUES (%s, %s, %s)", ("priority", value, i)) def setResolutionList(self, t): """Remove all resolutions, set them to `t` (index, name)""" self.dbCheck() with self.env.db_transaction as db: db("DELETE FROM enum WHERE type='resolution'") for value, name in t: db("INSERT INTO enum (type, name, value) VALUES (%s, %s, %s)", ("resolution", name, value)) def setComponentList(self, t): """Remove all components, set them to `t` (name, owner)""" self.dbCheck() with self.env.db_transaction as db: db("DELETE FROM component") for name, owner in t: db("INSERT INTO component (name, owner) VALUES (%s, %s)", (name, owner)) def setVersionList(self, v): """Remove all versions, set them to `v`""" self.dbCheck() with self.env.db_transaction as db: db("DELETE FROM version") for value in v: # time and description are also available db("INSERT INTO version (name) VALUES (%s)", value) def setMilestoneList(self, m): """Remove all milestones, set them to `m` (""" self.dbCheck() with self.env.db_transaction as db: db("DELETE FROM milestone") for value in m: # due, completed, description are also available db("INSERT INTO milestone (name) VALUES (%s)", value) def addTicket(self, type, time, changetime, component, priority, owner, reporter, cc, version, milestone, status, resolution, summary, description, keywords): """ ticket table db21.py format id integer PRIMARY KEY, type text, -- the nature of the ticket time integer, -- the time it was created changetime integer, component text, severity text, priority text, owner text, -- who is this ticket assigned to reporter text, cc text, -- email addresses to notify version text, -- milestone text, -- status text, resolution text, summary text, -- one-line summary description text, -- problem description (long) keywords text """ if status.lower() == 'open': if owner != '': status = 'assigned' else: status = 'new' with self.env.db_transaction as db: c = db.cursor() c.execute( """ INSERT INTO ticket (type, time, changetime, component, priority, owner, reporter, cc, version, milestone, status, resolution, summary, description, keywords) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """, (type, time, changetime, component, priority, owner, reporter, cc, version, milestone, status.lower(), resolution, summary, '%s' % description, keywords)) return db.get_last_id(c, 'ticket') def addTicketComment(self, ticket, time, author, value): with self.env.db_transaction as db: db( """ INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s) """, (ticket, time, author, 'comment', '', '%s' % value)) def addTicketChange(self, ticket, time, author, field, oldvalue, newvalue): with self.env.db_transaction as db: db( """INSERT INTO ticket_change (ticket, time, author, field, oldvalue, newvalue) VALUES (%s, %s, %s, %s, %s, %s) """, (ticket, time, author, field, oldvalue, newvalue))