docs: def pruneChanges(self, changeHorizon):
          """
          Called periodically by DBConnector, this method deletes changes older
          than C{changeHorizon}.
          """
  
          if not changeHorizon:
              return None
  
          def thd(conn):
              changes_tbl = self.db.model.changes
  
              # First, get the list of changes to delete.  This could be written
              # as a subquery but then that subquery would be run for every
              # table, which is very inefficient; also, MySQL's subquery support
              # leaves much to be desired, and doesn't support this particular
              # form.
              q = sa.select([changes_tbl.c.changeid],
                            order_by=[sa.desc(changes_tbl.c.changeid)],
                            offset=changeHorizon)
              res = conn.execute(q)
              ids_to_delete = [r.changeid for r in res]
  
              # and delete from all relevant tables, in dependency order
              for table_name in ('scheduler_changes', 'change_files',
                                 'change_properties', 'changes', 'change_users'):
                  remaining = ids_to_delete[:]
                  while remaining:
                      batch, remaining = remaining[:100], remaining[100:]
                      table = self.db.model.metadata.tables[table_name]
                      conn.execute(
                          table.delete(table.c.changeid.in_(batch)))
          yield self.db.pool.do(thd)