'Get bans from the database, merged into single ticket.
This is the same as `getBans`, but bans merged into single
ticket.
Parameters
jail : Jail
Jail that the ban belongs to. Default `None`; all jails.
bantime : int
Ban time in seconds, such that bans returned would still be
valid now. Negative values are equivalent to `None`.
Default `None`; no limit.
ip : str
IP Address to filter bans by. Default `None`; all IPs.
Returns
list or Ticket
Single ticket representing bans stored in database per IP
in a list. When `ip` argument passed, a single `Ticket` is
returned.'

def getBansMerged(self, ip=None, jail=None, bantime=None):

    with self._lock:
        cacheKey = None
        if ((bantime is None) or (bantime < 0)):
            cacheKey = (ip, jail)
            if (cacheKey in self._bansMergedCache):
                return self._bansMergedCache[cacheKey]
        tickets = []
        ticket = None
        results = list(self._getBans(ip=ip, jail=jail, bantime=bantime))
        if results:
            prev_banip = results[0][0]
            matches = []
            failures = 0
            tickdata = {}
            for (banip, timeofban, data) in results:
                if (banip != prev_banip):
                    ticket = FailTicket(prev_banip, prev_timeofban, matches)
                    ticket.setAttempt(failures)
                    tickets.append(ticket)
                    prev_banip = banip
                    matches = []
                    failures = 0
                    tickdata = {}
                m = data.get('matches', [])
                maxadd = (self.maxEntries - len(matches))
                if (maxadd > 0):
                    if (len(m) <= maxadd):
                        matches = (m + matches)
                    else:
                        matches = (m[(- maxadd):] + matches)
                failures += data.get('failures', 1)
                tickdata.update(data.get('data', {}))
                prev_timeofban = timeofban
            ticket = FailTicket(banip, prev_timeofban, matches)
            ticket.setAttempt(failures)
            ticket.setData(**tickdata)
            tickets.append(ticket)
        if cacheKey:
            self._bansMergedCache[cacheKey] = (tickets if (ip is None) else ticket)
        return (tickets if (ip is None) else ticket)
