Beispiel #1
0
    def find(self, rtype, key, val):
        """ Given a resource type & a single key/val find the model

        A single instantiated model object found by the key/val
        will be returned if a match is found in the database.
        If no record can be found then return None.

        WARN: This isn't for complex queries! Use search() instead.

        :return: model or None
        """

        model = rtype_to_model(rtype)
        param = {'key': key, 'val': val}
        query = """
                SELECT {cols} FROM {table}
                WHERE {key} = %(val)s;
                """

        query = query.format(
            cols=self.field_cols(model),
            key=key,
            table=rtype,
        )

        signals.pre_find.send(model.__class__, model=model)

        result = self.query(query, param=param)
        if result:
            result = model(result[0])
            signals.post_find.send(model.__class__, model=result)

        return result or None
Beispiel #2
0
def _validate_param(rtype, fields):
    """ Ensure the sparse fields exists on the models """

    try:
        # raises ValueError if not found
        model = rtype_to_model(rtype)
        model_fields = model.all_fields
    except ValueError:
        raise InvalidQueryParams(**{
            'detail': 'The fields query param provided with a '
                      'field type of "%s" is unknown.' % rtype,
            'links': LINK,
            'parameter': PARAM,
        })

    for field in fields:
        if field not in model_fields:
            raise InvalidQueryParams(**{
                'detail': 'The fields query param "TYPE" of "%s" '
                          'is not possible. It does not have a field '
                          'by the name of "%s".' % (rtype, field),
                'links': LINK,
                'parameter': PARAM,
            })
Beispiel #3
0
    def search(self, rtype, **kwargs):
        """ Search for the model by assorted criteria

        Quite a bit needs to happen for a search processing!

        The breakdown is we need to apply the query parameters
        where applicable. These include pagination, sorting,
        & filtering.

        Additionally, models can declare there own static
        filters or static query that should be applied. For
        static filters a model can opt-in with a `search_filters`
        property & for a static query to append a `search_query`
        property must be present.
        """

        model = rtype_to_model(rtype)
        param = {}
        pages = self.pages_query(kwargs.get('pages'))
        sorts = self.sorts_query(kwargs.get(
            'sorts', [Sortable(goldman.config.SORT)]
        ))

        query = """
                SELECT {cols}, count(*) OVER() as _count
                FROM {table}
                """
        query = query.format(
            cols=self.field_cols(model),
            table=rtype,
        )

        filters = kwargs.get('filters', [])
        filters += getattr(model, 'search_filters', []) or []

        if filters:
            where, param = self.filters_query(filters)
            query += where

        model_query = getattr(model, 'search_query', '') or ''
        if filters and model_query:
            model_query = ' AND ' + model_query
        elif model_query:
            model_query = ' WHERE ' + model_query

        query += model_query
        query += sorts
        query += pages

        signals.pre_search.send(model.__class__, model=model)

        result = self.query(query, param=param)
        models = [model(res) for res in result]

        if models:
            signals.post_search.send(model.__class__, models=result)

        pages = kwargs.get('pages')
        if pages and result:
            pages.total = result[0]['_count']

        return models