2017-04-19 11:30:12 +02:00

71 lines
2.0 KiB
Python

from django.conf import settings
from django.db import models
from django.db.models.aggregates import Max
class GroupConcat(models.Aggregate):
"""
Theoretically, this should work in Sqlite, PostgreSQL, and MySQL, but I've
only ever tested it in Sqlite.
"""
ENGINE_SQLITE = 1
ENGINE_POSTGRESQL = 2
ENGINE_MYSQL = 3
ENGINES = {
"django.db.backends.sqlite3": ENGINE_SQLITE,
"django.db.backends.postgresql_psycopg2": ENGINE_POSTGRESQL,
"django.db.backends.postgresql": ENGINE_POSTGRESQL,
"django.db.backends.mysql": ENGINE_MYSQL
}
def __init__(self, expression, separator="\n", **extra):
self.engine = self._get_engine()
self.function = self._get_function()
self.template = self._get_template(separator)
models.Aggregate.__init__(
self,
expression,
output_field=models.CharField(),
**extra
)
def _get_engine(self):
engine = settings.DATABASES["default"]["ENGINE"]
try:
return self.ENGINES[engine]
except KeyError:
raise NotImplementedError(
"There's currently no support for {} when it comes to group "
"concatenation in Paperless".format(engine)
)
def _get_function(self):
if self.engine == self.ENGINE_POSTGRESQL:
return "STRING_AGG"
return "GROUP_CONCAT"
def _get_template(self, separator):
if self.engine == self.ENGINE_MYSQL:
return "%(function)s(%(expressions)s SEPARATOR '{}')".format(
separator)
return "%(function)s(%(expressions)s, '{}')".format(separator)
class LogQuerySet(models.query.QuerySet):
def by_group(self):
return self.values("group").annotate(
time=Max("modified"),
messages=GroupConcat("message"),
).order_by("-time")
class LogManager(models.Manager):
def get_queryset(self):
return LogQuerySet(self.model, using=self._db)