neutron/neutron/db/_model_query.py

126 lines
4.5 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
NOTE: This module shall not be used by external projects. It will be moved
to neutron-lib in due course, and then it can be used from there.
"""
from neutron.common import utils
# Classes implementing extensions will register hooks into this dictionary
# for "augmenting" the "core way" of building a query for retrieving objects
# from a model class. Hooks are registered by invoking register_hook().
_model_query_hooks = {
# model1 : {
# hook1: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# hook2: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# ...
# },
# model2 : {
# hook1: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# hook2: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# ...
# },
# ...
}
def register_hook(model, name, query_hook, filter_hook,
result_filters=None):
"""Register a hook to be invoked when a query is executed.
:param model: The DB Model that the hook applies to.
:type model: sqlalchemy orm model
:param name: A name for the hook.
:type name: str
:param query_hook: The method to be called to augment the query.
:type query_hook: callable or None
:param filter_hook: A method to be called to augment the query filter.
:type filter_hook: callable or None
:param result_filters: A Method to be called to filter the query result.
:type result_filters: callable or None
Adds the hook components to the _model_query_hooks dict. Models are the
keys of this dict, whereas the value is another dict mapping hook names
to callables performing the hook.
Each hook has three components:
"query", used to build the query expression
"filter", used to build the filter expression
"result_filters", used for final filtering on the query result
Query hooks take as input the query being built and return a
transformed query expression.
def mymodel_query_hook(context, original_model, query):
augmented_query = ...
return augmented_query
Filter hooks take as input the filter expression being built and return
a transformed filter expression
def mymodel_filter_hook(context, original_model, filters):
refined_filters = ...
return refined_filters
Result filter hooks take as input the query expression and the filter
expression, and return a final transformed query expression.
def mymodel_result_filter_hook(query, filters):
final_filters = ...
return query.filter(final_filters)
"""
if callable(query_hook):
query_hook = utils.make_weak_ref(query_hook)
if callable(filter_hook):
filter_hook = utils.make_weak_ref(filter_hook)
if callable(result_filters):
result_filters = utils.make_weak_ref(result_filters)
_model_query_hooks.setdefault(model, {})[name] = {
'query': query_hook,
'filter': filter_hook,
'result_filters': result_filters
}
def get_hooks(model):
"""Retrieve the model query hooks for a model.
:param model: The DB Model to look up for query hooks.
:type model: sqlalchemy orm model
:return: list of hooks
:rtype: list of dict of callable
"""
return _model_query_hooks.get(model, {}).values()