Esempio n. 1
0
    def __init__(self, context, session=None):
        super(DatabaseManager, self).__init__(context)
        self.session = session

        if self.plugin is not None:
            self.perm_manager = DatabasePermissionsManager(self.context)
Esempio n. 2
0
class DatabaseManager(BaseManager):
    id_vals = ["id", "hashkey"]
    modify_vals = ["date"]
    get_vals = ["created", "updated"]
    vals = id_vals + modify_vals + get_vals

    def __init__(self, context, session=None):
        super(DatabaseManager, self).__init__(context)
        self.session = session

        if self.plugin is not None:
            self.perm_manager = DatabasePermissionsManager(self.context)

    def get_or_create(self, obj, query_data=False):
        new_obj = self.get(obj, query_data=query_data)
        if new_obj is None:
            new_obj = self.add(obj)
        else:
            new_obj = self.translate_object(new_obj)
        return new_obj

    def setup_model(self, obj):
        data = obj.get_data()

        metric = get_cls(self.session, Metric, obj.metric_proxy)
        source = get_cls(self.session, Source, obj.source_proxy, create=True)

        attribs = {
            'source': source,
            'metric': metric,
            'data': data,
            'plugin': self.plugin,
            'plugin_model_id': obj.plugin_model_proxy.hashkey,
            }

        if self.user is not None:
            attribs['user'] = self.user
        elif self.group is not None:
            attribs['group'] = self.group

        for v in self.modify_vals:
            attribs[v] = getattr(obj, v)

        return attribs

    def get(self, obj, query_data=False):
        attribs = self.setup_model(obj)
        if not query_data:
            del attribs['data']
        instance = self.session.query(obj.model_cls).filter_by(**attribs).first()
        return instance

    def add(self, obj):
        attribs = self.setup_model(obj)
        mod = obj.model_cls(**attribs)

        self.session.add(mod)
        self.commit()

        obj.id = mod.id
        obj.hashkey = mod.hashkey

        return obj

    def find_model(self, obj, **kwargs):
        q = self.session.query(obj.model_cls)
        for attr, value in kwargs.items():
            q = q.filter(getattr(obj.model_cls, attr) == value)
        if q.count() > 0:
            return q.first()
        else:
            raise InvalidObjectException()

    def commit(self):
        try:
            self.session.commit()
        except IntegrityError:
            log.exception("Found a duplicate record.")
            self.session.rollback()
            raise DuplicateRecord()

    def delete(self, obj):
        mod = self.find_model(obj, id=obj.id)
        if self.perm_manager.check_perms(mod, "delete"):
            self.session.delete(mod)
            self.commit()
        return obj

    def update(self, obj):
        mod = self.find_model(obj, id=obj.id)
        if self.perm_manager.check_perms(mod, "update"):
            for v in self.modify_vals:
                setattr(mod, v, getattr(obj, v))
            mod.data = obj.get_data()
            self.commit()
        return obj

    def query_models(self, plugin_proxy=None, metric_proxy=None, query_cls=PluginData):
        models = self.session.query(PluginModel).order_by("date")
        if plugin_proxy is not None:
            plugin = get_cls(self.session, Plugin, plugin_proxy, attrs=["hashkey"])
            models = models.filter(getattr(query_cls, "plugin") == plugin)

        if metric_proxy is not None:
            metric = get_cls(self.session, Metric, metric_proxy)
            models = models.filter(getattr(query_cls, "metric") == metric)
        return models.distinct()

    def _query_base(self, plugin_proxy=None, metric_proxy=None, query_cls=PluginData, plugin_model_proxy=None):
        query = self.session.query(query_cls).order_by("date")
        if self.user is not None:
            query = query.filter(getattr(query_cls, "user") == self.user)

        query = query.order_by(query_cls.date.asc())
        if plugin_proxy is not None:
            plugin = get_cls(self.session, Plugin, plugin_proxy, attrs=["hashkey"])
            query = query.filter(getattr(query_cls, "plugin") == plugin)

        if metric_proxy is not None:
            metric = get_cls(self.session, Metric, metric_proxy)
            query = query.filter(getattr(query_cls, "metric") == metric)

        if plugin_model_proxy is not None:
            plugin_model = get_cls(self.session, PluginModel, plugin_model_proxy, attrs=["hashkey"])
            query = query.filter(getattr(query_cls, "plugin_model") == plugin_model)

        return query

    def lookup_plugin_model(self, obj):
        from core.plugins.loader import plugins
        model_key = obj.plugin_model.hashkey
        plugin_key = obj.plugin.hashkey
        plugin = plugins[plugin_key]
        for m in plugin.models:
            if m.plugin_model_proxy.hashkey == model_key:
                return m
        return None

    def translate_object(self, obj):
        has_perm = self.perm_manager.check_perms(obj, "view")
        if not has_perm:
            log.info("Incorrect permissions.")
            return None

        tp = self.lookup_plugin_model(obj)()
        tp.metric_proxy = MetricProxy(name=obj.metric.name)
        tp.plugin_proxy = PluginProxy(name=obj.plugin.name, hashkey=obj.plugin.hashkey)
        tp.source_proxy = SourceProxy(name=obj.source.name)

        for v in self.vals:
            setattr(tp, v, getattr(obj, v))
        tp.set_data(obj.data)
        if obj.user is not None:
            tp.user = obj.user.email

        return tp

    def translate_objects(self, query):
        tps = []
        for obj in query:
            translation = self.translate_object(obj)
            if translation is not None:
                tps.append(translation)
        return tps

    def _query_range(self, query_column, model_cls, plugin_proxy=None, metric_proxy=None, start=None, end=None, plugin_model_proxy=None):
        query = self._query_base(plugin_proxy, metric_proxy, query_cls=model_cls, plugin_model_proxy=plugin_model_proxy)
        if start is not None:
            query = query.filter(getattr(model_cls, query_column) >= start)
        if end is not None:
            query = query.filter(getattr(model_cls, query_column) <= end)

        return self.translate_objects(query.all())

    def _query_filter(self, model_cls, plugin_proxy=None, metric_proxy=None, plugin_model_proxy=None, first=False, last=False, **kwargs):
        query = self._query_base(plugin_proxy, metric_proxy, query_cls=model_cls, plugin_model_proxy=plugin_model_proxy)
        for attr, value in kwargs.items():
            query = query.filter(getattr(model_cls, attr) == value)

        if first or last:
            if first:
                if query.count() > 0:
                    query = query.first()
                else:
                    return None
            if last:
                if query.count() > 0:
                    query = query[-1]
                else:
                    return None
            return self.translate_object(query)

        return self.translate_objects(query.all())

    def query_range(self, query_column, plugin_proxy=None, metric_proxy=None, start=None, end=None):
        return self._query_range(query_column, PluginData, plugin_proxy, metric_proxy, start, end)

    def query_filter(self, plugin_proxy=None, metric_proxy=None, **kwargs):
        return self._query_filter(PluginData, plugin_proxy, metric_proxy, **kwargs)

    def query_last(self, plugin_proxy=None, metric_proxy=None, **kwargs):
        return self._query_filter(PluginData, plugin_proxy, metric_proxy, last=True, **kwargs)

    def query_first(self, plugin_proxy=None, metric_proxy=None, **kwargs):
        return self._query_filter(PluginData, plugin_proxy, metric_proxy, first=True, **kwargs)

    def get_query_class(self, obj):
        from core.plugins.lib.models import PluginDataModel
        if issubclass(obj, PluginDataModel):
            query_cls = PluginData
        else:
            raise InvalidObjectException()
        return query_cls

    def query_class_filter(self, cls, **kwargs):
        query_cls = self.get_query_class(cls)
        return self._query_filter(query_cls, plugin_model_proxy=cls.plugin_model_proxy, **kwargs)

    def query_class_range(self, query_column, cls, start=None, end=None):
        query_cls = self.get_query_class(cls)
        return self._query_range(query_column, query_cls, plugin_model_proxy=cls.plugin_model_proxy, start=start, end=end)

    def register_plugin(self, plugin_cls):
        plugin_proxy = PluginProxy(name=plugin_cls.name, hashkey=plugin_cls.hashkey)
        plugin = get_cls(self.session, Plugin, plugin_proxy, attrs=["name", "hashkey"], create=True)
        if plugin_cls.models is not None:
            for m in plugin_cls.models:
                get_cls(self.session, Metric, m.metric_proxy, create=True)
                get_cls(self.session, Source, m.source_proxy, create=True)
                self.register_model(plugin_cls, m)
        return plugin

    def register_model(self, plugin_cls, model):
        proxy = PluginModelProxy(
            plugin_id=plugin_cls.hashkey,
            metric_id=model.metric_proxy.name,
            name=model.__name__
        )
        val = get_cls(self.session, PluginModel, proxy, attrs=["name", "plugin_id", "metric_id"], create=True)

        proxy.hashkey = val.hashkey
        model.plugin_model_proxy = proxy