source: timingandestimationplugin/branches/trac1.0-Permissions/timingandestimationplugin/reportmanager.py

Last change on this file was 14426, checked in by Russ Tyndall, 9 years ago

fixing report Primary Key bugs 1.4.6 fix #12010 fix #12191

File size: 7.0 KB
Line 
1from trac.core import *
2import dbhelper, trac, trac.db
3
4def tryint(val, default=0):
5  if not val: return default
6  try:
7    return int(val)
8  except ValueError:
9    return default
10
11class 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()
23
24  def upgrade(self):
25    self.env.log.debug("T&E Checking for custom_report upgrade")
26    # Check to see what version we have
27    version = tryint(dbhelper.get_system_value(self.env, self.name))
28    if version > self.version:
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 "
32                      "version %s of the file reportmanager.py (currently using version %s)."
33                      % (__name__, str(self.version), str(version)))
34
35      # Do the staged updates, I removed this: version < 1 and
36    if not dbhelper.db_table_exists(self.env, 'custom_report'):
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)")
46     
47        #if version < 2:
48
49    # Updates complete, set the version
50    dbhelper.set_system_value(self.env, self.name, self.version)
51    self.env.log.debug("T&E END Checking for custom_report upgrade")
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"
57    tpl = dbhelper.get_first_row(self.env, sql, uuid)
58    return tpl or (None, 0)
59   
60  def get_new_report_id (self):
61    """find the next available report id """
62    rtn = dbhelper.get_scalar(self.env, "SELECT MAX(id) FROM report")
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"""
67    return dbhelper.get_scalar(self.env, "SELECT MAX(ordering) FROM custom_report WHERE maingroup=%s AND subgroup=%s",
68                           0, maingroup, subgroup) or 0
69 
70  def _insert_report (self, 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))
74    new_id = []
75    @self.env.with_transaction()
76    def fn(db):
77        cur = db.cursor()
78        cur.execute("DELETE FROM custom_report WHERE uuid=%s", (uuid,))
79        cur.execute("INSERT INTO report (title, author, description, query) "
80                    "VALUES (%s, %s, %s, %s)",
81                    (title, author, description, query))
82        new_id.append(db.get_last_id(cur,'report'));
83        cur.execute("INSERT INTO custom_report "
84                    "(id, uuid, maingroup, subgroup, version, ordering) "
85                    "VALUES (%s, %s, %s, %s, %s, %s)",
86                    (new_id[0], uuid, maingroup, subgroup, version, ordering))
87    return new_id[0]
88   
89
90  def _update_report (self, id, title, author, description, query,
91                      maingroup, subgroup, version):
92    """Updates a report and its row in the custom_report table """
93    self.log.debug("Updating report '%s' with to version %s" % (title, version))
94    dbhelper.execute_in_trans(
95      self.env,
96      ("UPDATE report SET title=%s, author=%s, description=%s, query=%s " \
97         "WHERE id=%s", (title, author, description, query, id)),
98      ("UPDATE custom_report SET version=%s, maingroup=%s, subgroup=%s "
99       "WHERE id=%s", (version, maingroup, subgroup, id)))
100   
101  def add_report(self, title, author, description, query, uuid, version,
102                 maingroup, subgroup="", force=False):
103    """
104    We add/update a report to the system. We will not overwrite unchanged versions
105    unless force is set.
106    """
107    # First check to see if we can load an existing version of this report
108    (id, currentversion) = self.get_report_id_and_version(uuid)
109    self.log.debug("add_report %s (ver:%s) | id: %s currentversion: %s" % (uuid , version, id, currentversion))
110    try:
111      if not id:
112        ordering = self.get_max_ordering(maingroup, subgroup) + 1
113        next_id = self._insert_report(title, author, description, query, 
114                            uuid, maingroup, subgroup, version, ordering)
115        return True
116      if currentversion < version or force:
117        self._update_report(id, title, author, description, query,
118                            maingroup, subgroup, version)
119        return True
120    except Exception, e:
121      self.log.error("CustomReportManager.add_report Exception: %s, %s" % (e,(title, author, uuid, version,
122                 maingroup, subgroup, force)));
123    self.log.debug("report %s not upgraded (a better version already exists)" % uuid)
124    return False
125 
126  def get_report_by_uuid(self, uuid):
127    sql = "SELECT report.id,report.title FROM custom_report "\
128          "LEFT JOIN report ON custom_report.id=report.id "\
129          "WHERE custom_report.uuid=%s"
130    return dbhelper.get_first_row(self.env, sql,uuid)
131
132  def get_reports_by_group(self, group):
133    """Gets all of the reports for a given group"""
134    rv = {}
135    try:
136      res = dbhelper.get_result_set(
137        self.env, 
138        "SELECT custom_report.subgroup,report.id,report.title,"
139        " custom_report.version, custom_report.uuid "
140        "FROM custom_report "
141        "LEFT JOIN report ON custom_report.id=report.id "
142        "WHERE custom_report.maingroup=%s "
143        "ORDER BY custom_report.subgroup,custom_report.ordering", group)
144      if not res:
145        return rv
146      for subgroup, id, title, version, uuid in res.rows:
147        if not rv.has_key(subgroup):
148          rv[subgroup] = { "title": subgroup,
149                           "reports": [] }
150        rv[subgroup]["reports"].append( { "id": int(id), "title": title, "version":version, "uuid":uuid } )
151    except:
152      self.log.exception("Error getting reports by group")
153    return rv
154 
155  def get_version_hash_by_group(self, group):
156    """Gets all of the reports for a given group as a uuid=>version hash"""
157    rv = {}
158    try:
159      res = dbhelper.get_result_set(
160        self.env, 
161        "SELECT custom_report.subgroup,report.id,report.title,"
162        " custom_report.version, custom_report.uuid "
163        "FROM custom_report "
164        "LEFT JOIN report ON custom_report.id=report.id "
165        "WHERE custom_report.maingroup=%s "
166        "ORDER BY custom_report.subgroup,custom_report.ordering",
167        group)
168      if not res:
169        return rv;
170      for subgroup, id, title, version, uuid in res.rows:
171        rv[uuid] = version
172    except:
173      self.log.exception("Failed to get_version_hash_by_group")
174    return rv
Note: See TracBrowser for help on using the repository browser.