| [8124] | 1 | from trac.core import * |
|---|
| [9963] | 2 | import dbhelper, trac, trac.db |
|---|
| [8124] | 3 | |
|---|
| [8141] | 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() |
|---|
| [8141] | 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 |
|---|
| [8141] | 27 | version = tryint(dbhelper.get_system_value(self.env, self.name)) |
|---|
| [8124] | 28 | if version > self.version: |
|---|
| [8141] | 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)." |
|---|
| [8141] | 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'): |
|---|
| [8141] | 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 | |
|---|
| [8141] | 47 | #if version < 2: |
|---|
| [8124] | 48 | |
|---|
| [8141] | 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" |
|---|
| [8141] | 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 """ |
|---|
| [8141] | 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""" |
|---|
| [8141] | 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 | |
|---|
| 70 | def _insert_report (self, next_id, title, author, description, query, |
|---|
| 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)) |
|---|
| [8141] | 74 | dbhelper.execute_in_trans( |
|---|
| 75 | self.env, |
|---|
| 76 | ("DELETE FROM custom_report WHERE uuid=%s", (uuid,)), |
|---|
| 77 | ("INSERT INTO report (id, title, author, description, query) " \ |
|---|
| 78 | "VALUES (%s, %s, %s, %s, %s)", |
|---|
| 79 | (next_id, title, author, description, query)), |
|---|
| 80 | ("INSERT INTO custom_report (id, uuid, maingroup, subgroup, version, ordering) " \ |
|---|
| 81 | "VALUES (%s, %s, %s, %s, %s, %s)", |
|---|
| 82 | (next_id, uuid, maingroup, subgroup, version, ordering))) |
|---|
| [9963] | 83 | if type(self.env.get_read_db().cnx) == trac.db.postgres_backend.PostgreSQLConnection: |
|---|
| 84 | self.log.debug("Attempting to increment sequence (only works in postgres)") |
|---|
| [8202] | 85 | try: |
|---|
| 86 | dbhelper.execute_in_nested_trans(self.env, "update_seq", ("SELECT nextval('report_id_seq');",[])); |
|---|
| 87 | self.log.debug("Sequence updated"); |
|---|
| 88 | except: |
|---|
| 89 | self.log.debug("Sequence failed to update, perhaps you are not running postgres?"); |
|---|
| [8124] | 90 | |
|---|
| 91 | def _update_report (self, id, title, author, description, query, |
|---|
| 92 | maingroup, subgroup, version): |
|---|
| 93 | """Updates a report and its row in the custom_report table """ |
|---|
| 94 | self.log.debug("Updating report '%s' with to version %s" % (title, version)) |
|---|
| [8141] | 95 | dbhelper.execute_in_trans( |
|---|
| 96 | self.env, |
|---|
| 97 | ("UPDATE report SET title=%s, author=%s, description=%s, query=%s " \ |
|---|
| 98 | "WHERE id=%s", (title, author, description, query, id)), |
|---|
| 99 | ("UPDATE custom_report SET version=%s, maingroup=%s, subgroup=%s " |
|---|
| 100 | "WHERE id=%s", (version, maingroup, subgroup, id))) |
|---|
| [8124] | 101 | |
|---|
| 102 | def add_report(self, title, author, description, query, uuid, version, |
|---|
| 103 | maingroup, subgroup="", force=False): |
|---|
| 104 | """ |
|---|
| 105 | We add/update a report to the system. We will not overwrite unchanged versions |
|---|
| 106 | unless force is set. |
|---|
| 107 | """ |
|---|
| 108 | # First check to see if we can load an existing version of this report |
|---|
| 109 | (id, currentversion) = self.get_report_id_and_version(uuid) |
|---|
| 110 | self.log.debug("add_report %s (ver:%s) | id: %s currentversion: %s" % (uuid , version, id, currentversion)) |
|---|
| 111 | try: |
|---|
| 112 | if not id: |
|---|
| 113 | next_id = self.get_new_report_id() |
|---|
| 114 | ordering = self.get_max_ordering(maingroup, subgroup) + 1 |
|---|
| 115 | self._insert_report(next_id, title, author, description, query, |
|---|
| 116 | uuid, maingroup, subgroup, version, ordering) |
|---|
| 117 | return True |
|---|
| 118 | if currentversion < version or force: |
|---|
| 119 | self._update_report(id, title, author, description, query, |
|---|
| 120 | maingroup, subgroup, version) |
|---|
| 121 | return True |
|---|
| 122 | except Exception, e: |
|---|
| 123 | self.log.error("CustomReportManager.add_report Exception: %s, %s" % (e,(title, author, uuid, version, |
|---|
| 124 | maingroup, subgroup, force))); |
|---|
| 125 | self.log.debug("report %s not upgraded (a better version already exists)" % uuid) |
|---|
| 126 | return False |
|---|
| 127 | |
|---|
| 128 | def get_report_by_uuid(self, uuid): |
|---|
| 129 | sql = "SELECT report.id,report.title FROM custom_report "\ |
|---|
| 130 | "LEFT JOIN report ON custom_report.id=report.id "\ |
|---|
| 131 | "WHERE custom_report.uuid=%s" |
|---|
| [8141] | 132 | return dbhelper.get_first_row(self.env, sql,uuid) |
|---|
| [8124] | 133 | |
|---|
| 134 | def get_reports_by_group(self, group): |
|---|
| 135 | """Gets all of the reports for a given group""" |
|---|
| 136 | rv = {} |
|---|
| 137 | try: |
|---|
| [8141] | 138 | res = dbhelper.get_result_set( |
|---|
| 139 | self.env, |
|---|
| 140 | "SELECT custom_report.subgroup,report.id,report.title," |
|---|
| 141 | " custom_report.version, custom_report.uuid " |
|---|
| 142 | "FROM custom_report " |
|---|
| 143 | "LEFT JOIN report ON custom_report.id=report.id " |
|---|
| 144 | "WHERE custom_report.maingroup=%s " |
|---|
| 145 | "ORDER BY custom_report.subgroup,custom_report.ordering", group) |
|---|
| [8176] | 146 | if not res: |
|---|
| 147 | return rv |
|---|
| [8141] | 148 | for subgroup, id, title, version, uuid in res.rows: |
|---|
| [8124] | 149 | if not rv.has_key(subgroup): |
|---|
| 150 | rv[subgroup] = { "title": subgroup, |
|---|
| 151 | "reports": [] } |
|---|
| 152 | rv[subgroup]["reports"].append( { "id": int(id), "title": title, "version":version, "uuid":uuid } ) |
|---|
| 153 | except: |
|---|
| [8141] | 154 | self.log.exception("Error getting reports by group") |
|---|
| [8124] | 155 | return rv |
|---|
| 156 | |
|---|
| 157 | def get_version_hash_by_group(self, group): |
|---|
| 158 | """Gets all of the reports for a given group as a uuid=>version hash""" |
|---|
| 159 | rv = {} |
|---|
| 160 | try: |
|---|
| [8141] | 161 | res = dbhelper.get_result_set( |
|---|
| 162 | self.env, |
|---|
| 163 | "SELECT custom_report.subgroup,report.id,report.title," |
|---|
| 164 | " custom_report.version, custom_report.uuid " |
|---|
| 165 | "FROM custom_report " |
|---|
| 166 | "LEFT JOIN report ON custom_report.id=report.id " |
|---|
| 167 | "WHERE custom_report.maingroup=%s " |
|---|
| 168 | "ORDER BY custom_report.subgroup,custom_report.ordering", |
|---|
| 169 | group) |
|---|
| [8176] | 170 | if not res: |
|---|
| 171 | return rv; |
|---|
| [8141] | 172 | for subgroup, id, title, version, uuid in res.rows: |
|---|
| [8124] | 173 | rv[uuid] = version |
|---|
| 174 | except: |
|---|
| [8141] | 175 | self.log.exception("Failed to get_version_hash_by_group") |
|---|
| [8124] | 176 | return rv |
|---|