| [8124] | 1 | from trac.core import * |
|---|
| [9963] | 2 | import dbhelper, trac, trac.db |
|---|
| [8124] | 3 | |
|---|
| [8140] | 4 | def tryint(val, default=0): |
|---|
| 5 | if not val: return default |
|---|
| 6 | try: |
|---|
| 7 | return int(val) |
|---|
| 8 | except ValueError: |
|---|
| 9 | return default |
|---|
| 10 | |
|---|
| [8124] | 11 | class CustomReportManager: |
|---|
| 12 | """A Class to manage custom reports""" |
|---|
| 13 | version = 1 |
|---|
| 14 | name = "custom_report_manager_version" |
|---|
| 15 | env = None |
|---|
| 16 | log = None |
|---|
| 17 | TimingAndEstimationKey = "Timing and Estimation Plugin" |
|---|
| 18 | |
|---|
| 19 | def __init__(self, env, log): |
|---|
| 20 | self.env = env |
|---|
| 21 | self.log = log |
|---|
| 22 | self.upgrade() |
|---|
| [8140] | 23 | |
|---|
| 24 | def upgrade(self): |
|---|
| [9989] | 25 | self.env.log.debug("T&E Checking for custom_report upgrade") |
|---|
| [8124] | 26 | # Check to see what version we have |
|---|
| [8140] | 27 | version = tryint(dbhelper.get_system_value(self.env, self.name)) |
|---|
| [8124] | 28 | if version > self.version: |
|---|
| [8140] | 29 | raise TracError("Fatal Error: You appear to be running two plugins with" |
|---|
| 30 | " conflicting versions of the CustomReportManager class." |
|---|
| 31 | " Please ensure that '%s' is updated to " |
|---|
| [8124] | 32 | "version %s of the file reportmanager.py (currently using version %s)." |
|---|
| [8140] | 33 | % (__name__, str(self.version), str(version))) |
|---|
| 34 | |
|---|
| [11138] | 35 | # Do the staged updates, I removed this: version < 1 and |
|---|
| 36 | if not dbhelper.db_table_exists(self.env, 'custom_report'): |
|---|
| [8140] | 37 | dbhelper.execute_non_query( |
|---|
| 38 | self.env, |
|---|
| 39 | "CREATE TABLE custom_report (" |
|---|
| 40 | "id INTEGER," |
|---|
| 41 | "uuid VARCHAR(64)," |
|---|
| 42 | "maingroup VARCHAR(255)," |
|---|
| 43 | "subgroup VARCHAR(255)," |
|---|
| 44 | "version INTEGER," |
|---|
| 45 | "ordering INTEGER)") |
|---|
| [8124] | 46 | |
|---|
| [8140] | 47 | #if version < 2: |
|---|
| [8124] | 48 | |
|---|
| [8140] | 49 | # Updates complete, set the version |
|---|
| 50 | dbhelper.set_system_value(self.env, self.name, self.version) |
|---|
| [9989] | 51 | self.env.log.debug("T&E END Checking for custom_report upgrade") |
|---|
| [8124] | 52 | |
|---|
| 53 | def get_report_id_and_version (self, uuid): |
|---|
| 54 | sql = "SELECT custom_report.id, custom_report.version FROM custom_report "\ |
|---|
| 55 | "JOIN report ON report.id = custom_report.id " \ |
|---|
| 56 | "WHERE uuid=%s" |
|---|
| [8140] | 57 | tpl = dbhelper.get_first_row(self.env, sql, uuid) |
|---|
| [8124] | 58 | return tpl or (None, 0) |
|---|
| 59 | |
|---|
| 60 | def get_new_report_id (self): |
|---|
| 61 | """find the next available report id """ |
|---|
| [8140] | 62 | rtn = dbhelper.get_scalar(self.env, "SELECT MAX(id) FROM report") |
|---|
| [8124] | 63 | return (rtn and rtn+1) or 1 |
|---|
| 64 | |
|---|
| 65 | def get_max_ordering(self, maingroup, subgroup): |
|---|
| 66 | """ Find the maximum ordering value used for this group of the custom_report table""" |
|---|
| [8140] | 67 | return dbhelper.get_scalar(self.env, "SELECT MAX(ordering) FROM custom_report WHERE maingroup=%s AND subgroup=%s", |
|---|
| [8124] | 68 | 0, maingroup, subgroup) or 0 |
|---|
| 69 | |
|---|
| [14426] | 70 | def _insert_report (self, title, author, description, query, |
|---|
| [8124] | 71 | uuid, maingroup, subgroup, version, ordering): |
|---|
| 72 | """ Adds a row the custom_report_table """ |
|---|
| 73 | self.log.debug("Inserting new report '%s' with uuid '%s'" % (title,uuid)) |
|---|
| [14426] | 74 | new_id = [] |
|---|
| [16684] | 75 | with self.env.db_transaction as db: |
|---|
| [14426] | 76 | cur = db.cursor() |
|---|
| 77 | cur.execute("DELETE FROM custom_report WHERE uuid=%s", (uuid,)) |
|---|
| 78 | cur.execute("INSERT INTO report (title, author, description, query) " |
|---|
| 79 | "VALUES (%s, %s, %s, %s)", |
|---|
| 80 | (title, author, description, query)) |
|---|
| 81 | new_id.append(db.get_last_id(cur,'report')); |
|---|
| 82 | cur.execute("INSERT INTO custom_report " |
|---|
| 83 | "(id, uuid, maingroup, subgroup, version, ordering) " |
|---|
| 84 | "VALUES (%s, %s, %s, %s, %s, %s)", |
|---|
| 85 | (new_id[0], uuid, maingroup, subgroup, version, ordering)) |
|---|
| 86 | return new_id[0] |
|---|
| 87 | |
|---|
| [8124] | 88 | |
|---|
| 89 | def _update_report (self, id, title, author, description, query, |
|---|
| 90 | maingroup, subgroup, version): |
|---|
| 91 | """Updates a report and its row in the custom_report table """ |
|---|
| 92 | self.log.debug("Updating report '%s' with to version %s" % (title, version)) |
|---|
| [8140] | 93 | dbhelper.execute_in_trans( |
|---|
| 94 | self.env, |
|---|
| 95 | ("UPDATE report SET title=%s, author=%s, description=%s, query=%s " \ |
|---|
| 96 | "WHERE id=%s", (title, author, description, query, id)), |
|---|
| 97 | ("UPDATE custom_report SET version=%s, maingroup=%s, subgroup=%s " |
|---|
| 98 | "WHERE id=%s", (version, maingroup, subgroup, id))) |
|---|
| [8124] | 99 | |
|---|
| 100 | def add_report(self, title, author, description, query, uuid, version, |
|---|
| 101 | maingroup, subgroup="", force=False): |
|---|
| 102 | """ |
|---|
| 103 | We add/update a report to the system. We will not overwrite unchanged versions |
|---|
| 104 | unless force is set. |
|---|
| 105 | """ |
|---|
| 106 | # First check to see if we can load an existing version of this report |
|---|
| 107 | (id, currentversion) = self.get_report_id_and_version(uuid) |
|---|
| 108 | self.log.debug("add_report %s (ver:%s) | id: %s currentversion: %s" % (uuid , version, id, currentversion)) |
|---|
| 109 | try: |
|---|
| 110 | if not id: |
|---|
| 111 | ordering = self.get_max_ordering(maingroup, subgroup) + 1 |
|---|
| [14426] | 112 | next_id = self._insert_report(title, author, description, query, |
|---|
| 113 | uuid, maingroup, subgroup, version, ordering) |
|---|
| [8124] | 114 | return True |
|---|
| 115 | if currentversion < version or force: |
|---|
| 116 | self._update_report(id, title, author, description, query, |
|---|
| 117 | maingroup, subgroup, version) |
|---|
| 118 | return True |
|---|
| 119 | except Exception, e: |
|---|
| 120 | self.log.error("CustomReportManager.add_report Exception: %s, %s" % (e,(title, author, uuid, version, |
|---|
| 121 | maingroup, subgroup, force))); |
|---|
| 122 | self.log.debug("report %s not upgraded (a better version already exists)" % uuid) |
|---|
| 123 | return False |
|---|
| 124 | |
|---|
| 125 | def get_report_by_uuid(self, uuid): |
|---|
| 126 | sql = "SELECT report.id,report.title FROM custom_report "\ |
|---|
| 127 | "LEFT JOIN report ON custom_report.id=report.id "\ |
|---|
| 128 | "WHERE custom_report.uuid=%s" |
|---|
| [8140] | 129 | return dbhelper.get_first_row(self.env, sql,uuid) |
|---|
| [8124] | 130 | |
|---|
| 131 | def get_reports_by_group(self, group): |
|---|
| 132 | """Gets all of the reports for a given group""" |
|---|
| 133 | rv = {} |
|---|
| 134 | try: |
|---|
| [8140] | 135 | res = dbhelper.get_result_set( |
|---|
| 136 | self.env, |
|---|
| 137 | "SELECT custom_report.subgroup,report.id,report.title," |
|---|
| 138 | " custom_report.version, custom_report.uuid " |
|---|
| 139 | "FROM custom_report " |
|---|
| 140 | "LEFT JOIN report ON custom_report.id=report.id " |
|---|
| 141 | "WHERE custom_report.maingroup=%s " |
|---|
| 142 | "ORDER BY custom_report.subgroup,custom_report.ordering", group) |
|---|
| [8176] | 143 | if not res: |
|---|
| 144 | return rv |
|---|
| [8140] | 145 | for subgroup, id, title, version, uuid in res.rows: |
|---|
| [8124] | 146 | if not rv.has_key(subgroup): |
|---|
| 147 | rv[subgroup] = { "title": subgroup, |
|---|
| 148 | "reports": [] } |
|---|
| 149 | rv[subgroup]["reports"].append( { "id": int(id), "title": title, "version":version, "uuid":uuid } ) |
|---|
| 150 | except: |
|---|
| [8140] | 151 | self.log.exception("Error getting reports by group") |
|---|
| [8124] | 152 | return rv |
|---|
| 153 | |
|---|
| 154 | def get_version_hash_by_group(self, group): |
|---|
| 155 | """Gets all of the reports for a given group as a uuid=>version hash""" |
|---|
| 156 | rv = {} |
|---|
| 157 | try: |
|---|
| [8140] | 158 | res = dbhelper.get_result_set( |
|---|
| 159 | self.env, |
|---|
| 160 | "SELECT custom_report.subgroup,report.id,report.title," |
|---|
| 161 | " custom_report.version, custom_report.uuid " |
|---|
| 162 | "FROM custom_report " |
|---|
| 163 | "LEFT JOIN report ON custom_report.id=report.id " |
|---|
| 164 | "WHERE custom_report.maingroup=%s " |
|---|
| 165 | "ORDER BY custom_report.subgroup,custom_report.ordering", |
|---|
| 166 | group) |
|---|
| [8176] | 167 | if not res: |
|---|
| 168 | return rv; |
|---|
| [8140] | 169 | for subgroup, id, title, version, uuid in res.rows: |
|---|
| [8124] | 170 | rv[uuid] = version |
|---|
| 171 | except: |
|---|
| [8140] | 172 | self.log.exception("Failed to get_version_hash_by_group") |
|---|
| [8124] | 173 | return rv |
|---|