Commits

Jun Omae  committed 5c3b562

refactored trac/notification/model.py

  • Participants
  • Parent commits ed06c0b

Comments (0)

Files changed (1)

File trac/notification/model.py

 
 __all__ = ['Subscription']
 
+
 class Subscription(object):
 
+    __slots__ = ('env', 'values')
+
     fields = ('id', 'sid', 'authenticated', 'distributor', 'format',
-            'priority', 'adverb', 'class')
+              'priority', 'adverb', 'class')
 
     def __init__(self, env):
         self.env = env
             raise KeyError(name)
         self.values[name] = value
 
+    def _from_database(self, id, sid, authenticated, distributor, format,
+                       priority, adverb, class_):
+        self['id'] = id
+        self['sid'] = sid
+        self['authenticated'] = int(authenticated)
+        self['distributor'] = distributor
+        self['format'] = format
+        self['priority'] = int(priority)
+        self['adverb'] = adverb
+        self['class'] = class_
+
     @classmethod
     def add(cls, env, subscription):
         """id and priority overwritten."""
         with env.db_transaction as db:
-            priority = len(cls.find_by_sid_and_distributor(env,
-                subscription['sid'], subscription['authenticated'],
-                subscription['distributor']))+1
+            priority = len(cls.find_by_sid_and_distributor(
+                env, subscription['sid'], subscription['authenticated'],
+                subscription['distributor'])) + 1
             now = to_utimestamp(datetime.now(utc))
             db("""
-            INSERT INTO subscription
-                        (time, changetime, sid, authenticated, distributor,
-                        format, priority, adverb, class)
-                 VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
-            """, (now, now, subscription['sid'], int(subscription['authenticated']),
-            subscription['distributor'], subscription['format'],
-            int(priority), subscription['adverb'],
-            subscription['class']))
+                INSERT INTO subscription (time, changetime, sid, authenticated,
+                                          distributor, format, priority,
+                                          adverb, class)
+                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+            (now, now, subscription['sid'], int(subscription['authenticated']),
+             subscription['distributor'], subscription['format'],
+             int(priority), subscription['adverb'],
+             subscription['class']))
 
     @classmethod
     def delete(cls, env, rule_id):
         with env.db_transaction as db:
             cursor = db.cursor()
-            cursor.execute("""
-            SELECT sid, authenticated, distributor
-              FROM subscription
-             WHERE id=%s
-            """, (rule_id,))
+            cursor.execute("SELECT sid, authenticated, distributor "
+                           "FROM subscription WHERE id=%s",
+                           (rule_id,))
             sid, authenticated, distributor = cursor.fetchone()
-            cursor.execute("""
-            DELETE FROM subscription
-                  WHERE id = %s
-            """, (rule_id,))
+            cursor.execute("DELETE FROM subscription WHERE id = %s""",
+                           (rule_id,))
             i = 1
-            for s in cls.find_by_sid_and_distributor(env, sid, authenticated, distributor):
+            for s in cls.find_by_sid_and_distributor(env, sid, authenticated,
+                                                     distributor):
                 s['priority'] = i
                 s._update_priority()
                 i += 1
         with env.db_transaction as db:
             cursor = db.cursor()
             cursor.execute("""
-            SELECT sid, authenticated, distributor
-              FROM subscription
-             WHERE id=%s
+                SELECT sid, authenticated, distributor
+                  FROM subscription
+                 WHERE id=%s
             """, (rule_id,))
             sid, authenticated, distributor = cursor.fetchone()
-            if priority > len(cls.find_by_sid_and_distributor(env, sid, authenticated, distributor)):
+            subs = cls.find_by_sid_and_distributor(env, sid, authenticated,
+                                                   distributor)
+            if priority > len(subs):
                 return
             i = 1
-            for s in cls.find_by_sid_and_distributor(env, sid, authenticated, distributor):
+            for s in subs:
                 if int(s['id']) == int(rule_id):
                     s['priority'] = priority
                     s._update_priority()
                 else:
                     s['priority'] = i
                     s._update_priority()
-                i+=1
+                i += 1
 
     @classmethod
-    def update_format_by_distributor_and_sid(cls, env, distributor, sid, authenticated, format):
+    def update_format_by_distributor_and_sid(cls, env, distributor, sid,
+                                             authenticated, format):
         with env.db_transaction as db:
             db("""
-            UPDATE subscription
-               SET format=%s
-             WHERE distributor=%s
-               AND sid=%s
-               AND authenticated=%s
+                UPDATE subscription
+                   SET format=%s
+                 WHERE distributor=%s
+                   AND sid=%s
+                   AND authenticated=%s
             """, (format, distributor, sid, int(authenticated)))
 
     @classmethod
+    def _find(cls, env, **kwargs):
+        with env.db_query as db:
+            conditions = []
+            args = []
+            for name, value in sorted(kwargs.iteritems()):
+                if name.endswith('_'):
+                    name = name[:-1]
+                conditions.append(db.quote(name) + '=%s')
+                args.append(value)
+            query = 'SELECT id, sid, authenticated, distributor, format, ' \
+                    'priority, adverb, class FROM subscription'
+            if conditions:
+                query += ' WHERE ' + ' AND '.join(conditions)
+            query += ' ORDER BY priority'
+            cursor = db.cursor()
+            cursor.execute(query, args)
+            for row in cursor:
+                sub = Subscription(env)
+                sub._from_database(*row)
+                yield sub
+
+    @classmethod
     def find_by_sid_and_distributor(cls, env, sid, authenticated, distributor):
-        subs = []
-
-        with env.db_query as db:
-            cursor = db.cursor()
-            cursor.execute("""
-              SELECT id, sid, authenticated, distributor,
-                     format, priority, adverb, class
-                FROM subscription
-               WHERE sid=%s
-                 AND authenticated=%s
-                 AND distributor=%s
-            ORDER BY priority
-            """, (sid,int(authenticated),distributor))
-            for i in cursor:
-                sub = Subscription(env)
-                sub['id'] = i[0]
-                sub['sid'] = i[1]
-                sub['authenticated'] = i[2]
-                sub['distributor'] = i[3]
-                sub['format'] = i[4]
-                sub['priority'] = int(i[5])
-                sub['adverb'] = i[6]
-                sub['class'] = i[7]
-                subs.append(sub)
-
-        return subs
+        return list(cls._find(env, sid=sid, authenticated=int(authenticated),
+                              distributor=distributor))
 
     @classmethod
     def find_by_sids_and_class(cls, env, uids, klass):
         """uids should be a collection to tuples (sid, auth)"""
-        if not uids:
-            return []
-
         subs = []
-
-        with env.db_query as db:
-            cursor = db.cursor()
-            for sid, authenticated in uids:
-                cursor.execute("""
-                    SELECT id, sid, authenticated, distributor,
-                           format, priority, adverb, class
-                      FROM subscription
-                     WHERE class=%s
-                       AND sid = %s
-                       AND authenticated = %s
-                """, (klass,sid,int(authenticated)))
-                for i in cursor:
-                    sub = Subscription(env)
-                    sub['id'] = i[0]
-                    sub['sid'] = i[1]
-                    sub['authenticated'] = i[2]
-                    sub['distributor'] = i[3]
-                    sub['format'] = i[4]
-                    sub['priority'] = int(i[5])
-                    sub['adverb'] = i[6]
-                    sub['class'] = i[7]
-                    subs.append(sub)
-
+        for sid, authenticated in uids:
+            subs.extend(cls._find(env, class_=klass, sid=sid,
+                                  authenticated=int(authenticated)))
         return subs
 
     @classmethod
     def find_by_class(cls, env, klass):
-        subs = []
-
-        with env.db_query as db:
-            cursor = db.cursor()
-            cursor.execute("""
-                SELECT id, sid, authenticated, distributor,
-                       format, priority, adverb, class
-                  FROM subscription
-                 WHERE class=%s
-            """, (klass,))
-            for i in cursor:
-                sub = Subscription(env)
-                sub['id'] = i[0]
-                sub['sid'] = i[1]
-                sub['authenticated'] = i[2]
-                sub['distributor'] = i[3]
-                sub['format'] = i[4]
-                sub['priority'] = int(i[5])
-                sub['adverb'] = i[6]
-                sub['class'] = i[7]
-                subs.append(sub)
-
-        return subs
+        return list(cls._find(env, class_=klass))
 
     def subscription_tuple(self):
         return (
             cursor = db.cursor()
             now = to_utimestamp(datetime.now(utc))
             cursor.execute("""
-            UPDATE subscription
-               SET changetime=%s,
-                   priority=%s
-             WHERE id=%s
+                UPDATE subscription
+                   SET changetime=%s, priority=%s
+                 WHERE id=%s
             """, (now, int(self.values['priority']), self.values['id']))