예제 #1
0
파일: api.py 프로젝트: kowalski/featdjango
def get_graph(method, name, params):

    Action = action.MetaAction.new(
        name, ActionCategories.retrieve,
        effects=[call.model_perform(method.__name__)],
        params=params,
        result_info=value.InterfaceValue(graph.IGraph))

    annotate.injectClassCallback(name, 4, 'annotate_action', name, Action)

    return method
예제 #2
0
def get_graph(method, name, params):

    Action = action.MetaAction.new(
        name,
        ActionCategories.retrieve,
        effects=[call.model_perform(method.__name__)],
        params=params,
        result_info=value.InterfaceValue(graph.IGraph))

    annotate.injectClassCallback(name, 4, 'annotate_action', name, Action)

    return method
예제 #3
0
    def testParameterfiltering(self):
        model = Dummy()
        context = {"model": model}

        eff = call.model_perform("param_filtering", 1)
        res = yield eff(0, context, tata=2)
        self.assertEqual(res, (0, 1, 2, None, None))
        res = yield eff(0, context, tata=2, tutu=3)
        self.assertEqual(res, (0, 1, 2, None, 3))
        res = yield eff(0, context, tata=2, spam=42)
        self.assertEqual(res, (0, 1, 2, None, None))

        eff = call.model_perform("param_filtering", 1, tata=2)
        res = yield eff(0, context)
        self.assertEqual(res, (0, 1, 2, None, None))
        res = yield eff(0, context, foo=33)
        self.assertEqual(res, (0, 1, 2, None, None))
        res = yield eff(0, context, tutu=3)
        self.assertEqual(res, (0, 1, 2, None, 3))
        res = yield eff(0, context, tata=88)
        self.assertEqual(res, (0, 1, 88, None, None))
예제 #4
0
    def testDelayCall(self):
        model = Dummy()
        context = {"model": model}

        eff = effect.delay(call.model_perform("perform"), "nop", 0.1)

        self.assertEqual(model.value, None)
        d = eff("spam", context)
        self.assertEqual(model.value, None)
        res = yield d
        self.assertEqual(res, "nop")
        self.assertEqual(model.value, None)
        yield common.delay(None, 0.1)
        self.assertEqual(model.value, "spam")
예제 #5
0
파일: models.py 프로젝트: f3at/feat
    def __init__(cls, name, bases, dct):
        cls._query_target = None
        cls._query_model = None
        cls._connection_getter = None
        cls._static_conditions = None
        cls._factory = None
        cls._fetch_documents_set = False
        cls._fetch_documents = staticmethod(effect.identity)
        cls._item_field = None

        # this processes all the annotations
        super(QueryViewMeta, cls).__init__(name, bases, dct)

        if cls._factory is None:
            # The class is not annotated with view_factory() annotations
            # This is only valid in the base class, althought no actions
            # should be created.
            return

        # validate that the required annotations have been called
        if cls._query_target is None:
            raise ValueError("This model needs to be annotated with "
                             "query_target(source|view)")

        if not callable(cls._connection_getter):
            raise ValueError("This model needs to be annotated with "
                             "db_connection(effect) annotation")

        # define the Select and Count actions
        name = utils.mk_class_name(cls._factory.name, "Query")
        QueryValue = MetaQueryValue.new(name, cls._factory,
                                        cls._allowed_fields,
                                        cls._include_value)
        result_info = value.Model()

        name = utils.mk_class_name(cls._factory.name, "IncludeValue")
        IncludeValue = value.MetaCollection.new(
            name, [value.FixedValues(cls._allowed_fields)])

        name = utils.mk_class_name(cls._factory.name, "AggregateValue")
        AggregateValue = value.MetaCollection.new(
            name, [value.FixedValues(cls._model_aggregations.keys())])

        build_query = parse_incoming_query(cls._factory,
                                           cls._static_conditions,
                                           cls._include_value,
                                           cls._model_aggregations)

        def render_select_response(value, context, *args, **kwargs):
            cls = type(context['model'])
            if not cls._query_set_factory:
                # query set collection is created only once per class type
                factory = MetaQueryResult.new(cls)
                factory.annotate_meta('json', 'render-as-list')
                cls._query_set_factory = factory
            if cls._fetch_documents_set:
                context['result'].update(value)

            # convert all the aggregate values using their IValueInfo
            if kwargs.get('aggregate'):
                raw_values = context['result'].aggregations
                context['result'].aggregations = dict()
                for index, name in enumerate(kwargs['aggregate']):
                    value_info = cls._model_aggregations[name][0]
                    v = raw_values[index]
                    try:
                        published = value_info.publish(v)
                    except Exception as e:
                        error.handle_exception(
                            None, e, "Failed publishing the result %r", v)
                    else:
                        context['result'].aggregations[name] = published

            result = cls._query_set_factory(context['source'],
                                            context['result'])
            return result.initiate(view=context['view'],
                                   officer=context.get('officer'),
                                   aspect=context.get('aspect'))

        def store_select_result(value, context, *args, **kwargs):
            context['result'], context['responses'] = value
            return value[0]

        def do_include_value(value, context, *args, **kwargs):
            # If there was a custom routing for fetching items defined,
            # we need to call the include_value() explicitely. If
            # query.select() was used, there is no need for that.
            cls = context['model']
            if context['query'].include_value and cls._fetch_documents_set:
                return query.include_values(value, context['responses'],
                                            context['query'])
            else:
                return value

        SelectAction = action.MetaAction.new(
            utils.mk_class_name(cls._factory.name, "Select"),
            ActionCategories.retrieve,
            is_idempotent=False, result_info=result_info,
            effects=(
                build_query,
                call.model_perform('do_select'),
                store_select_result,
                cls._fetch_documents,
                do_include_value,
                render_select_response,
                ),
            params=[action.Param('query', QueryValue()),
                    action.Param('include_value', IncludeValue(),
                                 is_required=False),
                    action.Param('sorting', SortField(cls._allowed_fields),
                                 is_required=False),
                    action.Param('skip', value.Integer(0), is_required=False),
                    action.Param('limit', value.Integer(), is_required=False),
                    action.Param('aggregate', AggregateValue(),
                                 is_required=False),
                    ])
        cls.annotate_action(u"select", SelectAction)

        # define count action
        CountAction = action.MetaAction.new(
            utils.mk_class_name(cls._factory.name, "Count"),
            ActionCategories.retrieve,
            effects=[
                build_query,
                call.model_perform('do_count')],
            result_info=value.Integer(),
            is_idempotent=False,
            params=[action.Param('query', QueryValue())])
        cls.annotate_action(u"count", CountAction)

        # define values action (fetch the values for the range)
        ValuesAction = action.MetaAction.new(
            utils.mk_class_name(cls._factory.name, "Values"),
            ActionCategories.retrieve,
            effects=[
                build_query,
                call.model_perform('fetch_values')],
            # FIXME: the result is a dictionary of name -> [values],
            # consider creating the IValidator for this structure
            result_info=value.Value(),
            is_idempotent=False,
            params=[action.Param('query', QueryValue()),
                    action.Param('fields', IncludeValue())])
        cls.annotate_action(u"values", ValuesAction)

        # define how to fetch items
        if cls._item_field:

            def fetch_names(value, context):
                model = context['model']
                d = build_query(None, context, query=cls._factory())
                d.addCallback(defer.inject_param, 1,
                              query.values, model.connection, cls._item_field)
                return d

            cls.annotate_child_names(fetch_names)

            def fetch_matching(value, context):
                c = query.Condition(
                    cls._item_field, query.Evaluator.equals, context['key'])
                q = cls._factory(c)
                d = build_query(None, context, query=q)
                d.addCallback(context['model'].do_select, skip=0)
                # the result on this points (rows, responses)
                d.addCallback(lambda (r, _): r)
                d.addCallback(cls._fetch_documents, context)

                def unpack(result):
                    if result:
                        return result[0]

                d.addCallback(unpack)
                return d

            def fetch_source(value, context):
                if cls._query_target == 'source':
                    return fetch_matching(value, context)
                else:
                    return context['model'].source

            cls.annotate_child_source(fetch_source)

            def fetch_view(value, context):
                if cls._query_target == 'view':
                    return fetch_matching(value, context)
                else:
                    return context['view']

            cls.annotate_child_view(fetch_view)
예제 #6
0
파일: models.py 프로젝트: zaheerm/feat
    def annotate_view_factory(cls, factory, allowed_fields=[],
                              static_conditions=None,
                              fetch_documents=None):
        cls._view = IQueryViewFactory(factory)
        cls._static_conditions = (static_conditions and
                                  model._validate_effect(static_conditions))
        if not fetch_documents:
            cls._fetch_documents_set = False
            fetch_documents = effect.identity
        else:
            cls._fetch_documents_set = True
            fetch_documents = fetch_documents

        for x in allowed_fields:
            if not cls._view.has_field(x):
                raise ValueError("%r doesn't define a field: '%s'" % (cls, x))
        cls._allowed_fields = allowed_fields

        # define query action
        name = utils.mk_class_name(cls._view.name, "Query")
        QueryValue = MetaQueryValue.new(name, cls._view, cls._allowed_fields)
        name = utils.mk_class_name(cls._view.name, "Sorting")
        SortingValue = MetaSortingValue.new(name, cls._allowed_fields)
        result_info = value.Model()

        def get_static_conditions(value, context, *args, **kwargs):

            def build_query(static_conditions, factory, q):
                subquery = query.Query(factory, *static_conditions)
                return query.Query(factory, q, query.Operator.AND, subquery)

            cls = type(context['model'])
            if cls._static_conditions:
                d = cls._static_conditions(None, context)
                d.addCallback(build_query, cls._view, kwargs['query'])
                return d
            return defer.succeed(kwargs['query'])

        SelectAction = action.MetaAction.new(
            utils.mk_class_name(cls._view.name, "Select"),
            ActionCategories.retrieve,
            is_idempotent=False, result_info=result_info,
            effects=[
                get_static_conditions,
                call.model_perform('do_select'),
                fetch_documents,
                call.model_filter('render_select_response')],
            params=[action.Param('query', QueryValue()),
                    action.Param('sorting', SortingValue(), is_required=False),
                    action.Param('skip', value.Integer(0), is_required=False),
                    action.Param('limit', value.Integer(), is_required=False)])
        cls.annotate_action(u"select", SelectAction)

        # define count action
        CountAction = action.MetaAction.new(
            utils.mk_class_name(cls._view.name, "Count"),
            ActionCategories.retrieve,
            effects=[
                get_static_conditions,
                call.model_perform('do_count')],
            result_info=value.Integer(),
            is_idempotent=False,
            params=[action.Param('query', QueryValue())])
        cls.annotate_action(u"count", CountAction)