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)