Eager loading on One-to-X foreign keys
In this changeset, I added ORM relationships to the DB models concerning the already-declared foreign keys. I also modified the DB query building to now handle a new 'eager' parameter that, if True, is responsible to also fetch the data relative to these 'parent' DB entities (no cascading). Change-Id: Ieea181af9a4b173c54621dcc6c549161f5a35aeb Partially-Implements: blueprint watcher-versioned-objects
This commit is contained in:
@@ -36,7 +36,7 @@ class BaseConnection(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_goal_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None, eager=False):
|
||||
"""Get specific columns for matching goals.
|
||||
|
||||
Return a list of the specified columns for all goals that
|
||||
@@ -50,6 +50,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -72,31 +73,34 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_goal_by_id(self, context, goal_id):
|
||||
def get_goal_by_id(self, context, goal_id, eager=False):
|
||||
"""Return a goal given its ID.
|
||||
|
||||
:param context: The security context
|
||||
:param goal_id: The ID of a goal
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A goal
|
||||
:raises: :py:class:`~.GoalNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_goal_by_uuid(self, context, goal_uuid):
|
||||
def get_goal_by_uuid(self, context, goal_uuid, eager=False):
|
||||
"""Return a goal given its UUID.
|
||||
|
||||
:param context: The security context
|
||||
:param goal_uuid: The UUID of a goal
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A goal
|
||||
:raises: :py:class:`~.GoalNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_goal_by_name(self, context, goal_name):
|
||||
def get_goal_by_name(self, context, goal_name, eager=False):
|
||||
"""Return a goal given its name.
|
||||
|
||||
:param context: The security context
|
||||
:param goal_name: The name of a goal
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A goal
|
||||
:raises: :py:class:`~.GoalNotFound`
|
||||
"""
|
||||
@@ -129,9 +133,17 @@ class BaseConnection(object):
|
||||
:raises: :py:class:`~.Invalid`
|
||||
"""
|
||||
|
||||
def soft_delete_goal(self, goal_id):
|
||||
"""Soft delete a goal.
|
||||
|
||||
:param goal_id: The id or uuid of a goal.
|
||||
:raises: :py:class:`~.GoalNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_strategy_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None,
|
||||
eager=True):
|
||||
"""Get specific columns for matching strategies.
|
||||
|
||||
Return a list of the specified columns for all strategies that
|
||||
@@ -146,6 +158,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: Direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -170,31 +183,34 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_strategy_by_id(self, context, strategy_id):
|
||||
def get_strategy_by_id(self, context, strategy_id, eager=False):
|
||||
"""Return a strategy given its ID.
|
||||
|
||||
:param context: The security context
|
||||
:param strategy_id: The ID of a strategy
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A strategy
|
||||
:raises: :py:class:`~.StrategyNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_strategy_by_uuid(self, context, strategy_uuid):
|
||||
def get_strategy_by_uuid(self, context, strategy_uuid, eager=False):
|
||||
"""Return a strategy given its UUID.
|
||||
|
||||
:param context: The security context
|
||||
:param strategy_uuid: The UUID of a strategy
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A strategy
|
||||
:raises: :py:class:`~.StrategyNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_strategy_by_name(self, context, strategy_name):
|
||||
def get_strategy_by_name(self, context, strategy_name, eager=False):
|
||||
"""Return a strategy given its name.
|
||||
|
||||
:param context: The security context
|
||||
:param strategy_name: The name of a strategy
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A strategy
|
||||
:raises: :py:class:`~.StrategyNotFound`
|
||||
"""
|
||||
@@ -217,10 +233,17 @@ class BaseConnection(object):
|
||||
:raises: :py:class:`~.Invalid`
|
||||
"""
|
||||
|
||||
def soft_delete_strategy(self, strategy_id):
|
||||
"""Soft delete a strategy.
|
||||
|
||||
:param strategy_id: The id or uuid of a strategy.
|
||||
:raises: :py:class:`~.StrategyNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_audit_template_list(self, context, filters=None,
|
||||
limit=None, marker=None, sort_key=None,
|
||||
sort_dir=None):
|
||||
sort_dir=None, eager=False):
|
||||
"""Get specific columns for matching audit templates.
|
||||
|
||||
Return a list of the specified columns for all audit templates that
|
||||
@@ -234,6 +257,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -258,37 +282,43 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_audit_template_by_id(self, context, audit_template_id):
|
||||
def get_audit_template_by_id(self, context, audit_template_id,
|
||||
eager=False):
|
||||
"""Return an audit template.
|
||||
|
||||
:param context: The security context
|
||||
:param audit_template_id: The id of an audit template.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An audit template.
|
||||
:raises: :py:class:`~.AuditTemplateNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_audit_template_by_uuid(self, context, audit_template_uuid):
|
||||
def get_audit_template_by_uuid(self, context, audit_template_uuid,
|
||||
eager=False):
|
||||
"""Return an audit template.
|
||||
|
||||
:param context: The security context
|
||||
:param audit_template_uuid: The uuid of an audit template.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An audit template.
|
||||
:raises: :py:class:`~.AuditTemplateNotFound`
|
||||
"""
|
||||
|
||||
def get_audit_template_by_name(self, context, audit_template_name):
|
||||
def get_audit_template_by_name(self, context, audit_template_name,
|
||||
eager=False):
|
||||
"""Return an audit template.
|
||||
|
||||
:param context: The security context
|
||||
:param audit_template_name: The name of an audit template.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An audit template.
|
||||
:raises: :py:class:`~.AuditTemplateNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def destroy_audit_template(self, audit_template_id):
|
||||
"""Destroy an audit_template.
|
||||
"""Destroy an audit template.
|
||||
|
||||
:param audit_template_id: The id or uuid of an audit template.
|
||||
:raises: :py:class:`~.AuditTemplateNotFound`
|
||||
@@ -306,7 +336,7 @@ class BaseConnection(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def soft_delete_audit_template(self, audit_template_id):
|
||||
"""Soft delete an audit_template.
|
||||
"""Soft delete an audit template.
|
||||
|
||||
:param audit_template_id: The id or uuid of an audit template.
|
||||
:raises: :py:class:`~.AuditTemplateNotFound`
|
||||
@@ -314,7 +344,7 @@ class BaseConnection(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_audit_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None, eager=False):
|
||||
"""Get specific columns for matching audits.
|
||||
|
||||
Return a list of the specified columns for all audits that match the
|
||||
@@ -328,6 +358,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -351,21 +382,23 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_audit_by_id(self, context, audit_id):
|
||||
def get_audit_by_id(self, context, audit_id, eager=False):
|
||||
"""Return an audit.
|
||||
|
||||
:param context: The security context
|
||||
:param audit_id: The id of an audit.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An audit.
|
||||
:raises: :py:class:`~.AuditNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_audit_by_uuid(self, context, audit_uuid):
|
||||
def get_audit_by_uuid(self, context, audit_uuid, eager=False):
|
||||
"""Return an audit.
|
||||
|
||||
:param context: The security context
|
||||
:param audit_uuid: The uuid of an audit.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An audit.
|
||||
:raises: :py:class:`~.AuditNotFound`
|
||||
"""
|
||||
@@ -392,13 +425,13 @@ class BaseConnection(object):
|
||||
"""Soft delete an audit and all associated action plans.
|
||||
|
||||
:param audit_id: The id or uuid of an audit.
|
||||
:returns: An audit.
|
||||
:raises: :py:class:`~.AuditNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_action_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None,
|
||||
eager=False):
|
||||
"""Get specific columns for matching actions.
|
||||
|
||||
Return a list of the specified columns for all actions that match the
|
||||
@@ -412,6 +445,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -436,21 +470,23 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_action_by_id(self, context, action_id):
|
||||
def get_action_by_id(self, context, action_id, eager=False):
|
||||
"""Return a action.
|
||||
|
||||
:param context: The security context
|
||||
:param action_id: The id of a action.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A action.
|
||||
:raises: :py:class:`~.ActionNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_action_by_uuid(self, context, action_uuid):
|
||||
def get_action_by_uuid(self, context, action_uuid, eager=False):
|
||||
"""Return a action.
|
||||
|
||||
:param context: The security context
|
||||
:param action_uuid: The uuid of a action.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A action.
|
||||
:raises: :py:class:`~.ActionNotFound`
|
||||
"""
|
||||
@@ -475,10 +511,17 @@ class BaseConnection(object):
|
||||
:raises: :py:class:`~.Invalid`
|
||||
"""
|
||||
|
||||
def soft_delete_action(self, action_id):
|
||||
"""Soft delete an action.
|
||||
|
||||
:param action_id: The id or uuid of an action.
|
||||
:raises: :py:class:`~.ActionNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_action_plan_list(
|
||||
self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None, eager=False):
|
||||
"""Get specific columns for matching action plans.
|
||||
|
||||
Return a list of the specified columns for all action plans that
|
||||
@@ -492,6 +535,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -506,21 +550,23 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_action_plan_by_id(self, context, action_plan_id):
|
||||
def get_action_plan_by_id(self, context, action_plan_id, eager=False):
|
||||
"""Return an action plan.
|
||||
|
||||
:param context: The security context
|
||||
:param action_plan_id: The id of an action plan.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An action plan.
|
||||
:raises: :py:class:`~.ActionPlanNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_action_plan_by_uuid(self, context, action_plan__uuid):
|
||||
def get_action_plan_by_uuid(self, context, action_plan__uuid, eager=False):
|
||||
"""Return a action plan.
|
||||
|
||||
:param context: The security context
|
||||
:param action_plan__uuid: The uuid of an action plan.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An action plan.
|
||||
:raises: :py:class:`~.ActionPlanNotFound`
|
||||
"""
|
||||
@@ -545,9 +591,17 @@ class BaseConnection(object):
|
||||
:raises: :py:class:`~.Invalid`
|
||||
"""
|
||||
|
||||
def soft_delete_action_plan(self, action_plan_id):
|
||||
"""Soft delete an action plan.
|
||||
|
||||
:param action_plan_id: The id or uuid of an action plan.
|
||||
:raises: :py:class:`~.ActionPlanNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_efficacy_indicator_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None,
|
||||
eager=False):
|
||||
"""Get specific columns for matching efficacy indicators.
|
||||
|
||||
Return a list of the specified columns for all efficacy indicators that
|
||||
@@ -564,6 +618,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: Direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -588,31 +643,37 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_efficacy_indicator_by_id(self, context, efficacy_indicator_id):
|
||||
def get_efficacy_indicator_by_id(self, context, efficacy_indicator_id,
|
||||
eager=False):
|
||||
"""Return an efficacy indicator given its ID.
|
||||
|
||||
:param context: The security context
|
||||
:param efficacy_indicator_id: The ID of an efficacy indicator
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An efficacy indicator
|
||||
:raises: :py:class:`~.EfficacyIndicatorNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_efficacy_indicator_by_uuid(self, context, efficacy_indicator_uuid):
|
||||
def get_efficacy_indicator_by_uuid(self, context, efficacy_indicator_uuid,
|
||||
eager=False):
|
||||
"""Return an efficacy indicator given its UUID.
|
||||
|
||||
:param context: The security context
|
||||
:param efficacy_indicator_uuid: The UUID of an efficacy indicator
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An efficacy indicator
|
||||
:raises: :py:class:`~.EfficacyIndicatorNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_efficacy_indicator_by_name(self, context, efficacy_indicator_name):
|
||||
def get_efficacy_indicator_by_name(self, context, efficacy_indicator_name,
|
||||
eager=False):
|
||||
"""Return an efficacy indicator given its name.
|
||||
|
||||
:param context: The security context
|
||||
:param efficacy_indicator_name: The name of an efficacy indicator
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: An efficacy indicator
|
||||
:raises: :py:class:`~.EfficacyIndicatorNotFound`
|
||||
"""
|
||||
@@ -626,7 +687,7 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_efficacy_indicator(self, efficacy_indicator_uuid, values):
|
||||
def update_efficacy_indicator(self, efficacy_indicator_id, values):
|
||||
"""Update properties of an efficacy indicator.
|
||||
|
||||
:param efficacy_indicator_uuid: The UUID of an efficacy indicator
|
||||
@@ -638,7 +699,7 @@ class BaseConnection(object):
|
||||
@abc.abstractmethod
|
||||
def get_scoring_engine_list(
|
||||
self, context, columns=None, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None, eager=False):
|
||||
"""Get specific columns for matching scoring engines.
|
||||
|
||||
Return a list of the specified columns for all scoring engines that
|
||||
@@ -654,6 +715,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -668,31 +730,37 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_scoring_engine_by_id(self, context, scoring_engine_id):
|
||||
def get_scoring_engine_by_id(self, context, scoring_engine_id,
|
||||
eager=False):
|
||||
"""Return a scoring engine by its id.
|
||||
|
||||
:param context: The security context
|
||||
:param scoring_engine_id: The id of a scoring engine.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A scoring engine.
|
||||
:raises: :py:class:`~.ScoringEngineNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_scoring_engine_by_uuid(self, context, scoring_engine_uuid):
|
||||
def get_scoring_engine_by_uuid(self, context, scoring_engine_uuid,
|
||||
eager=False):
|
||||
"""Return a scoring engine by its uuid.
|
||||
|
||||
:param context: The security context
|
||||
:param scoring_engine_uuid: The uuid of a scoring engine.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A scoring engine.
|
||||
:raises: :py:class:`~.ScoringEngineNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_scoring_engine_by_name(self, context, scoring_engine_name):
|
||||
def get_scoring_engine_by_name(self, context, scoring_engine_name,
|
||||
eager=False):
|
||||
"""Return a scoring engine by its name.
|
||||
|
||||
:param context: The security context
|
||||
:param scoring_engine_name: The name of a scoring engine.
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A scoring engine.
|
||||
:raises: :py:class:`~.ScoringEngineNotFound`
|
||||
"""
|
||||
@@ -716,8 +784,8 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_service_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
def get_service_list(self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None, eager=False):
|
||||
"""Get specific columns for matching services.
|
||||
|
||||
Return a list of the specified columns for all services that
|
||||
@@ -732,6 +800,7 @@ class BaseConnection(object):
|
||||
:param sort_key: Attribute by which results should be sorted.
|
||||
:param sort_dir: Direction in which results should be sorted.
|
||||
(asc, desc)
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A list of tuples of the specified columns.
|
||||
"""
|
||||
|
||||
@@ -755,21 +824,23 @@ class BaseConnection(object):
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_service_by_id(self, context, service_id):
|
||||
def get_service_by_id(self, context, service_id, eager=False):
|
||||
"""Return a service given its ID.
|
||||
|
||||
:param context: The security context
|
||||
:param service_id: The ID of a service
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A service
|
||||
:raises: :py:class:`~.ServiceNotFound`
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_service_by_name(self, context, service_name):
|
||||
def get_service_by_name(self, context, service_name, eager=False):
|
||||
"""Return a service given its name.
|
||||
|
||||
:param context: The security context
|
||||
:param service_name: The name of a service
|
||||
:param eager: If True, also loads One-to-X data (Default: False)
|
||||
:returns: A service
|
||||
:raises: :py:class:`~.ServiceNotFound`
|
||||
"""
|
||||
|
||||
@@ -24,7 +24,10 @@ from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_db.sqlalchemy import session as db_session
|
||||
from oslo_db.sqlalchemy import utils as db_utils
|
||||
from oslo_utils import timeutils
|
||||
from sqlalchemy.inspection import inspect
|
||||
from sqlalchemy.orm import exc
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from watcher._i18n import _
|
||||
from watcher.common import exception
|
||||
@@ -34,7 +37,6 @@ from watcher.db.sqlalchemy import models
|
||||
from watcher.objects import action as action_objects
|
||||
from watcher.objects import action_plan as ap_objects
|
||||
from watcher.objects import audit as audit_objects
|
||||
from watcher.objects import utils as objutils
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
@@ -133,8 +135,9 @@ class Connection(api.BaseConnection):
|
||||
def __add_simple_filter(self, query, model, fieldname, value, operator_):
|
||||
field = getattr(model, fieldname)
|
||||
|
||||
if field.type.python_type is datetime.datetime:
|
||||
value = objutils.datetime_or_str_or_none(value)
|
||||
if field.type.python_type is datetime.datetime and value:
|
||||
if not isinstance(value, datetime.datetime):
|
||||
value = timeutils.parse_isotime(value)
|
||||
|
||||
return query.filter(self.valid_operators[operator_](field, value))
|
||||
|
||||
@@ -233,8 +236,20 @@ class Connection(api.BaseConnection):
|
||||
|
||||
return query
|
||||
|
||||
def _get(self, context, model, fieldname, value):
|
||||
@staticmethod
|
||||
def _set_eager_options(model, query):
|
||||
relationships = inspect(model).relationships
|
||||
for relationship in relationships:
|
||||
if not relationship.uselist:
|
||||
# We have a One-to-X relationship
|
||||
query = query.options(joinedload(relationship.key))
|
||||
return query
|
||||
|
||||
def _get(self, context, model, fieldname, value, eager):
|
||||
query = model_query(model)
|
||||
if eager:
|
||||
query = self._set_eager_options(model, query)
|
||||
|
||||
query = query.filter(getattr(model, fieldname) == value)
|
||||
if not context.show_deleted:
|
||||
query = query.filter(model.deleted_at.is_(None))
|
||||
@@ -246,7 +261,8 @@ class Connection(api.BaseConnection):
|
||||
|
||||
return obj
|
||||
|
||||
def _update(self, model, id_, values):
|
||||
@staticmethod
|
||||
def _update(model, id_, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(model, session=session)
|
||||
@@ -259,7 +275,8 @@ class Connection(api.BaseConnection):
|
||||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def _soft_delete(self, model, id_):
|
||||
@staticmethod
|
||||
def _soft_delete(model, id_):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(model, session=session)
|
||||
@@ -271,7 +288,8 @@ class Connection(api.BaseConnection):
|
||||
|
||||
query.soft_delete()
|
||||
|
||||
def _destroy(self, model, id_):
|
||||
@staticmethod
|
||||
def _destroy(model, id_):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(model, session=session)
|
||||
@@ -398,10 +416,11 @@ class Connection(api.BaseConnection):
|
||||
|
||||
# ### GOALS ### #
|
||||
|
||||
def get_goal_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
|
||||
def get_goal_list(self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None, eager=False):
|
||||
query = model_query(models.Goal)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.Goal, query)
|
||||
query = self._add_goals_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter_by(deleted_at=None)
|
||||
@@ -422,21 +441,24 @@ class Connection(api.BaseConnection):
|
||||
raise exception.GoalAlreadyExists(uuid=values['uuid'])
|
||||
return goal
|
||||
|
||||
def _get_goal(self, context, fieldname, value):
|
||||
def _get_goal(self, context, fieldname, value, eager):
|
||||
try:
|
||||
return self._get(context, model=models.Goal,
|
||||
fieldname=fieldname, value=value)
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.GoalNotFound(goal=value)
|
||||
|
||||
def get_goal_by_id(self, context, goal_id):
|
||||
return self._get_goal(context, fieldname="id", value=goal_id)
|
||||
def get_goal_by_id(self, context, goal_id, eager=False):
|
||||
return self._get_goal(
|
||||
context, fieldname="id", value=goal_id, eager=eager)
|
||||
|
||||
def get_goal_by_uuid(self, context, goal_uuid):
|
||||
return self._get_goal(context, fieldname="uuid", value=goal_uuid)
|
||||
def get_goal_by_uuid(self, context, goal_uuid, eager=False):
|
||||
return self._get_goal(
|
||||
context, fieldname="uuid", value=goal_uuid, eager=eager)
|
||||
|
||||
def get_goal_by_name(self, context, goal_name):
|
||||
return self._get_goal(context, fieldname="name", value=goal_name)
|
||||
def get_goal_by_name(self, context, goal_name, eager=False):
|
||||
return self._get_goal(
|
||||
context, fieldname="name", value=goal_name, eager=eager)
|
||||
|
||||
def destroy_goal(self, goal_id):
|
||||
try:
|
||||
@@ -463,9 +485,11 @@ class Connection(api.BaseConnection):
|
||||
# ### STRATEGIES ### #
|
||||
|
||||
def get_strategy_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
|
||||
marker=None, sort_key=None, sort_dir=None,
|
||||
eager=True):
|
||||
query = model_query(models.Strategy)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.Strategy, query)
|
||||
query = self._add_strategies_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter_by(deleted_at=None)
|
||||
@@ -486,23 +510,24 @@ class Connection(api.BaseConnection):
|
||||
raise exception.StrategyAlreadyExists(uuid=values['uuid'])
|
||||
return strategy
|
||||
|
||||
def _get_strategy(self, context, fieldname, value):
|
||||
def _get_strategy(self, context, fieldname, value, eager):
|
||||
try:
|
||||
return self._get(context, model=models.Strategy,
|
||||
fieldname=fieldname, value=value)
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.StrategyNotFound(strategy=value)
|
||||
|
||||
def get_strategy_by_id(self, context, strategy_id):
|
||||
return self._get_strategy(context, fieldname="id", value=strategy_id)
|
||||
|
||||
def get_strategy_by_uuid(self, context, strategy_uuid):
|
||||
def get_strategy_by_id(self, context, strategy_id, eager=False):
|
||||
return self._get_strategy(
|
||||
context, fieldname="uuid", value=strategy_uuid)
|
||||
context, fieldname="id", value=strategy_id, eager=eager)
|
||||
|
||||
def get_strategy_by_name(self, context, strategy_name):
|
||||
def get_strategy_by_uuid(self, context, strategy_uuid, eager=False):
|
||||
return self._get_strategy(
|
||||
context, fieldname="name", value=strategy_name)
|
||||
context, fieldname="uuid", value=strategy_uuid, eager=eager)
|
||||
|
||||
def get_strategy_by_name(self, context, strategy_name, eager=False):
|
||||
return self._get_strategy(
|
||||
context, fieldname="name", value=strategy_name, eager=eager)
|
||||
|
||||
def destroy_strategy(self, strategy_id):
|
||||
try:
|
||||
@@ -529,9 +554,12 @@ class Connection(api.BaseConnection):
|
||||
# ### AUDIT TEMPLATES ### #
|
||||
|
||||
def get_audit_template_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None,
|
||||
eager=False):
|
||||
|
||||
query = model_query(models.AuditTemplate)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.AuditTemplate, query)
|
||||
query = self._add_audit_templates_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter_by(deleted_at=None)
|
||||
@@ -561,24 +589,27 @@ class Connection(api.BaseConnection):
|
||||
audit_template=values['name'])
|
||||
return audit_template
|
||||
|
||||
def _get_audit_template(self, context, fieldname, value):
|
||||
def _get_audit_template(self, context, fieldname, value, eager):
|
||||
try:
|
||||
return self._get(context, model=models.AuditTemplate,
|
||||
fieldname=fieldname, value=value)
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.AuditTemplateNotFound(audit_template=value)
|
||||
|
||||
def get_audit_template_by_id(self, context, audit_template_id):
|
||||
def get_audit_template_by_id(self, context, audit_template_id,
|
||||
eager=False):
|
||||
return self._get_audit_template(
|
||||
context, fieldname="id", value=audit_template_id)
|
||||
context, fieldname="id", value=audit_template_id, eager=eager)
|
||||
|
||||
def get_audit_template_by_uuid(self, context, audit_template_uuid):
|
||||
def get_audit_template_by_uuid(self, context, audit_template_uuid,
|
||||
eager=False):
|
||||
return self._get_audit_template(
|
||||
context, fieldname="uuid", value=audit_template_uuid)
|
||||
context, fieldname="uuid", value=audit_template_uuid, eager=eager)
|
||||
|
||||
def get_audit_template_by_name(self, context, audit_template_name):
|
||||
def get_audit_template_by_name(self, context, audit_template_name,
|
||||
eager=False):
|
||||
return self._get_audit_template(
|
||||
context, fieldname="name", value=audit_template_name)
|
||||
context, fieldname="name", value=audit_template_name, eager=eager)
|
||||
|
||||
def destroy_audit_template(self, audit_template_id):
|
||||
try:
|
||||
@@ -609,8 +640,10 @@ class Connection(api.BaseConnection):
|
||||
# ### AUDITS ### #
|
||||
|
||||
def get_audit_list(self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
sort_key=None, sort_dir=None, eager=False):
|
||||
query = model_query(models.Audit)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.Audit, query)
|
||||
query = self._add_audits_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter(
|
||||
@@ -636,30 +669,20 @@ class Connection(api.BaseConnection):
|
||||
raise exception.AuditAlreadyExists(uuid=values['uuid'])
|
||||
return audit
|
||||
|
||||
def get_audit_by_id(self, context, audit_id):
|
||||
query = model_query(models.Audit)
|
||||
query = query.filter_by(id=audit_id)
|
||||
def _get_audit(self, context, fieldname, value, eager):
|
||||
try:
|
||||
audit = query.one()
|
||||
if not context.show_deleted:
|
||||
if audit.state == audit_objects.State.DELETED:
|
||||
raise exception.AuditNotFound(audit=audit_id)
|
||||
return audit
|
||||
except exc.NoResultFound:
|
||||
raise exception.AuditNotFound(audit=audit_id)
|
||||
return self._get(context, model=models.Audit,
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.AuditNotFound(audit=value)
|
||||
|
||||
def get_audit_by_uuid(self, context, audit_uuid):
|
||||
query = model_query(models.Audit)
|
||||
query = query.filter_by(uuid=audit_uuid)
|
||||
def get_audit_by_id(self, context, audit_id, eager=False):
|
||||
return self._get_audit(
|
||||
context, fieldname="id", value=audit_id, eager=eager)
|
||||
|
||||
try:
|
||||
audit = query.one()
|
||||
if not context.show_deleted:
|
||||
if audit.state == audit_objects.State.DELETED:
|
||||
raise exception.AuditNotFound(audit=audit_uuid)
|
||||
return audit
|
||||
except exc.NoResultFound:
|
||||
raise exception.AuditNotFound(audit=audit_uuid)
|
||||
def get_audit_by_uuid(self, context, audit_uuid, eager=False):
|
||||
return self._get_audit(
|
||||
context, fieldname="uuid", value=audit_uuid, eager=eager)
|
||||
|
||||
def destroy_audit(self, audit_id):
|
||||
def is_audit_referenced(session, audit_id):
|
||||
@@ -704,8 +727,10 @@ class Connection(api.BaseConnection):
|
||||
# ### ACTIONS ### #
|
||||
|
||||
def get_action_list(self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
sort_key=None, sort_dir=None, eager=False):
|
||||
query = model_query(models.Action)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.Action, query)
|
||||
query = self._add_actions_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter(
|
||||
@@ -726,31 +751,20 @@ class Connection(api.BaseConnection):
|
||||
raise exception.ActionAlreadyExists(uuid=values['uuid'])
|
||||
return action
|
||||
|
||||
def get_action_by_id(self, context, action_id):
|
||||
query = model_query(models.Action)
|
||||
query = query.filter_by(id=action_id)
|
||||
def _get_action(self, context, fieldname, value, eager):
|
||||
try:
|
||||
action = query.one()
|
||||
if not context.show_deleted:
|
||||
if action.state == action_objects.State.DELETED:
|
||||
raise exception.ActionNotFound(
|
||||
action=action_id)
|
||||
return action
|
||||
except exc.NoResultFound:
|
||||
raise exception.ActionNotFound(action=action_id)
|
||||
return self._get(context, model=models.Action,
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.ActionNotFound(action=value)
|
||||
|
||||
def get_action_by_uuid(self, context, action_uuid):
|
||||
query = model_query(models.Action)
|
||||
query = query.filter_by(uuid=action_uuid)
|
||||
try:
|
||||
action = query.one()
|
||||
if not context.show_deleted:
|
||||
if action.state == action_objects.State.DELETED:
|
||||
raise exception.ActionNotFound(
|
||||
action=action_uuid)
|
||||
return action
|
||||
except exc.NoResultFound:
|
||||
raise exception.ActionNotFound(action=action_uuid)
|
||||
def get_action_by_id(self, context, action_id, eager=False):
|
||||
return self._get_action(
|
||||
context, fieldname="id", value=action_id, eager=eager)
|
||||
|
||||
def get_action_by_uuid(self, context, action_uuid, eager=False):
|
||||
return self._get_action(
|
||||
context, fieldname="uuid", value=action_uuid, eager=eager)
|
||||
|
||||
def destroy_action(self, action_id):
|
||||
session = get_session()
|
||||
@@ -765,12 +779,12 @@ class Connection(api.BaseConnection):
|
||||
# NOTE(dtantsur): this can lead to very strange errors
|
||||
if 'uuid' in values:
|
||||
raise exception.Invalid(
|
||||
message=_("Cannot overwrite UUID for an existing "
|
||||
"Action."))
|
||||
message=_("Cannot overwrite UUID for an existing Action."))
|
||||
|
||||
return self._do_update_action(action_id, values)
|
||||
|
||||
def _do_update_action(self, action_id, values):
|
||||
@staticmethod
|
||||
def _do_update_action(action_id, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Action, session=session)
|
||||
@@ -799,9 +813,11 @@ class Connection(api.BaseConnection):
|
||||
# ### ACTION PLANS ### #
|
||||
|
||||
def get_action_plan_list(
|
||||
self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None, eager=False):
|
||||
query = model_query(models.ActionPlan)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.ActionPlan, query)
|
||||
query = self._add_action_plans_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter(
|
||||
@@ -824,32 +840,20 @@ class Connection(api.BaseConnection):
|
||||
raise exception.ActionPlanAlreadyExists(uuid=values['uuid'])
|
||||
return action_plan
|
||||
|
||||
def get_action_plan_by_id(self, context, action_plan_id):
|
||||
query = model_query(models.ActionPlan)
|
||||
query = query.filter_by(id=action_plan_id)
|
||||
def _get_action_plan(self, context, fieldname, value, eager):
|
||||
try:
|
||||
action_plan = query.one()
|
||||
if not context.show_deleted:
|
||||
if action_plan.state == ap_objects.State.DELETED:
|
||||
raise exception.ActionPlanNotFound(
|
||||
action_plan=action_plan_id)
|
||||
return action_plan
|
||||
except exc.NoResultFound:
|
||||
raise exception.ActionPlanNotFound(action_plan=action_plan_id)
|
||||
return self._get(context, model=models.ActionPlan,
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.ActionPlanNotFound(action_plan=value)
|
||||
|
||||
def get_action_plan_by_uuid(self, context, action_plan__uuid):
|
||||
query = model_query(models.ActionPlan)
|
||||
query = query.filter_by(uuid=action_plan__uuid)
|
||||
def get_action_plan_by_id(self, context, action_plan_id, eager=False):
|
||||
return self._get_action_plan(
|
||||
context, fieldname="id", value=action_plan_id, eager=eager)
|
||||
|
||||
try:
|
||||
action_plan = query.one()
|
||||
if not context.show_deleted:
|
||||
if action_plan.state == ap_objects.State.DELETED:
|
||||
raise exception.ActionPlanNotFound(
|
||||
action_plan=action_plan__uuid)
|
||||
return action_plan
|
||||
except exc.NoResultFound:
|
||||
raise exception.ActionPlanNotFound(action_plan=action_plan__uuid)
|
||||
def get_action_plan_by_uuid(self, context, action_plan_uuid, eager=False):
|
||||
return self._get_action_plan(
|
||||
context, fieldname="uuid", value=action_plan_uuid, eager=eager)
|
||||
|
||||
def destroy_action_plan(self, action_plan_id):
|
||||
def is_action_plan_referenced(session, action_plan_id):
|
||||
@@ -883,7 +887,8 @@ class Connection(api.BaseConnection):
|
||||
|
||||
return self._do_update_action_plan(action_plan_id, values)
|
||||
|
||||
def _do_update_action_plan(self, action_plan_id, values):
|
||||
@staticmethod
|
||||
def _do_update_action_plan(action_plan_id, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.ActionPlan, session=session)
|
||||
@@ -912,9 +917,12 @@ class Connection(api.BaseConnection):
|
||||
# ### EFFICACY INDICATORS ### #
|
||||
|
||||
def get_efficacy_indicator_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
marker=None, sort_key=None, sort_dir=None,
|
||||
eager=False):
|
||||
|
||||
query = model_query(models.EfficacyIndicator)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.EfficacyIndicator, query)
|
||||
query = self._add_efficacy_indicators_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter_by(deleted_at=None)
|
||||
@@ -935,24 +943,30 @@ class Connection(api.BaseConnection):
|
||||
raise exception.EfficacyIndicatorAlreadyExists(uuid=values['uuid'])
|
||||
return efficacy_indicator
|
||||
|
||||
def _get_efficacy_indicator(self, context, fieldname, value):
|
||||
def _get_efficacy_indicator(self, context, fieldname, value, eager):
|
||||
try:
|
||||
return self._get(context, model=models.EfficacyIndicator,
|
||||
fieldname=fieldname, value=value)
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.EfficacyIndicatorNotFound(efficacy_indicator=value)
|
||||
|
||||
def get_efficacy_indicator_by_id(self, context, efficacy_indicator_id):
|
||||
def get_efficacy_indicator_by_id(self, context, efficacy_indicator_id,
|
||||
eager=False):
|
||||
return self._get_efficacy_indicator(
|
||||
context, fieldname="id", value=efficacy_indicator_id)
|
||||
context, fieldname="id",
|
||||
value=efficacy_indicator_id, eager=eager)
|
||||
|
||||
def get_efficacy_indicator_by_uuid(self, context, efficacy_indicator_uuid):
|
||||
def get_efficacy_indicator_by_uuid(self, context, efficacy_indicator_uuid,
|
||||
eager=False):
|
||||
return self._get_efficacy_indicator(
|
||||
context, fieldname="uuid", value=efficacy_indicator_uuid)
|
||||
context, fieldname="uuid",
|
||||
value=efficacy_indicator_uuid, eager=eager)
|
||||
|
||||
def get_efficacy_indicator_by_name(self, context, efficacy_indicator_name):
|
||||
def get_efficacy_indicator_by_name(self, context, efficacy_indicator_name,
|
||||
eager=False):
|
||||
return self._get_efficacy_indicator(
|
||||
context, fieldname="name", value=efficacy_indicator_name)
|
||||
context, fieldname="name",
|
||||
value=efficacy_indicator_name, eager=eager)
|
||||
|
||||
def update_efficacy_indicator(self, efficacy_indicator_id, values):
|
||||
if 'uuid' in values:
|
||||
@@ -995,9 +1009,11 @@ class Connection(api.BaseConnection):
|
||||
plain_fields=plain_fields)
|
||||
|
||||
def get_scoring_engine_list(
|
||||
self, context, columns=None, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
self, context, columns=None, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None, eager=False):
|
||||
query = model_query(models.ScoringEngine)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.ScoringEngine, query)
|
||||
query = self._add_scoring_engine_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter_by(deleted_at=None)
|
||||
@@ -1019,24 +1035,27 @@ class Connection(api.BaseConnection):
|
||||
raise exception.ScoringEngineAlreadyExists(uuid=values['uuid'])
|
||||
return scoring_engine
|
||||
|
||||
def _get_scoring_engine(self, context, fieldname, value):
|
||||
def _get_scoring_engine(self, context, fieldname, value, eager):
|
||||
try:
|
||||
return self._get(context, model=models.ScoringEngine,
|
||||
fieldname=fieldname, value=value)
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.ScoringEngineNotFound(scoring_engine=value)
|
||||
|
||||
def get_scoring_engine_by_id(self, context, scoring_engine_id):
|
||||
def get_scoring_engine_by_id(self, context, scoring_engine_id,
|
||||
eager=False):
|
||||
return self._get_scoring_engine(
|
||||
context, fieldname="id", value=scoring_engine_id)
|
||||
context, fieldname="id", value=scoring_engine_id, eager=eager)
|
||||
|
||||
def get_scoring_engine_by_uuid(self, context, scoring_engine_uuid):
|
||||
def get_scoring_engine_by_uuid(self, context, scoring_engine_uuid,
|
||||
eager=False):
|
||||
return self._get_scoring_engine(
|
||||
context, fieldname="uuid", value=scoring_engine_uuid)
|
||||
context, fieldname="uuid", value=scoring_engine_uuid, eager=eager)
|
||||
|
||||
def get_scoring_engine_by_name(self, context, scoring_engine_name):
|
||||
def get_scoring_engine_by_name(self, context, scoring_engine_name,
|
||||
eager=False):
|
||||
return self._get_scoring_engine(
|
||||
context, fieldname="name", value=scoring_engine_name)
|
||||
context, fieldname="name", value=scoring_engine_name, eager=eager)
|
||||
|
||||
def destroy_scoring_engine(self, scoring_engine_id):
|
||||
try:
|
||||
@@ -1046,9 +1065,9 @@ class Connection(api.BaseConnection):
|
||||
scoring_engine=scoring_engine_id)
|
||||
|
||||
def update_scoring_engine(self, scoring_engine_id, values):
|
||||
if 'id' in values:
|
||||
if 'uuid' in values:
|
||||
raise exception.Invalid(
|
||||
message=_("Cannot overwrite ID for an existing "
|
||||
message=_("Cannot overwrite UUID for an existing "
|
||||
"Scoring Engine."))
|
||||
|
||||
try:
|
||||
@@ -1077,9 +1096,11 @@ class Connection(api.BaseConnection):
|
||||
query=query, model=models.Service, filters=filters,
|
||||
plain_fields=plain_fields)
|
||||
|
||||
def get_service_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
def get_service_list(self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None, eager=False):
|
||||
query = model_query(models.Service)
|
||||
if eager:
|
||||
query = self._set_eager_options(models.Service, query)
|
||||
query = self._add_services_filters(query, filters)
|
||||
if not context.show_deleted:
|
||||
query = query.filter_by(deleted_at=None)
|
||||
@@ -1096,18 +1117,20 @@ class Connection(api.BaseConnection):
|
||||
host=values['host'])
|
||||
return service
|
||||
|
||||
def _get_service(self, context, fieldname, value):
|
||||
def _get_service(self, context, fieldname, value, eager):
|
||||
try:
|
||||
return self._get(context, model=models.Service,
|
||||
fieldname=fieldname, value=value)
|
||||
fieldname=fieldname, value=value, eager=eager)
|
||||
except exception.ResourceNotFound:
|
||||
raise exception.ServiceNotFound(service=value)
|
||||
|
||||
def get_service_by_id(self, context, service_id):
|
||||
return self._get_service(context, fieldname="id", value=service_id)
|
||||
def get_service_by_id(self, context, service_id, eager=False):
|
||||
return self._get_service(
|
||||
context, fieldname="id", value=service_id, eager=eager)
|
||||
|
||||
def get_service_by_name(self, context, service_name):
|
||||
return self._get_service(context, fieldname="name", value=service_name)
|
||||
def get_service_by_name(self, context, service_name, eager=False):
|
||||
return self._get_service(
|
||||
context, fieldname="name", value=service_name, eager=eager)
|
||||
|
||||
def destroy_service(self, service_id):
|
||||
try:
|
||||
|
||||
@@ -27,6 +27,7 @@ from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy import Integer
|
||||
from sqlalchemy import Numeric
|
||||
from sqlalchemy import orm
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy import Text
|
||||
from sqlalchemy.types import TypeDecorator, TEXT
|
||||
@@ -57,6 +58,7 @@ def table_args():
|
||||
|
||||
class JsonEncodedType(TypeDecorator):
|
||||
"""Abstract base type serialized as json-encoded string in db."""
|
||||
|
||||
type = None
|
||||
impl = TEXT
|
||||
|
||||
@@ -81,11 +83,13 @@ class JsonEncodedType(TypeDecorator):
|
||||
|
||||
class JSONEncodedDict(JsonEncodedType):
|
||||
"""Represents dict serialized as json-encoded string in db."""
|
||||
|
||||
type = dict
|
||||
|
||||
|
||||
class JSONEncodedList(JsonEncodedType):
|
||||
"""Represents list serialized as json-encoded string in db."""
|
||||
|
||||
type = list
|
||||
|
||||
|
||||
@@ -111,23 +115,6 @@ class WatcherBase(models.SoftDeleteMixin,
|
||||
Base = declarative_base(cls=WatcherBase)
|
||||
|
||||
|
||||
class Strategy(Base):
|
||||
"""Represents a strategy."""
|
||||
|
||||
__tablename__ = 'strategies'
|
||||
__table_args__ = (
|
||||
UniqueConstraint('uuid', name='uniq_strategies0uuid'),
|
||||
UniqueConstraint('name', 'deleted', name='uniq_strategies0name'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(63), nullable=False)
|
||||
display_name = Column(String(63), nullable=False)
|
||||
goal_id = Column(Integer, ForeignKey('goals.id'), nullable=False)
|
||||
parameters_spec = Column(JSONEncodedDict, nullable=True)
|
||||
|
||||
|
||||
class Goal(Base):
|
||||
"""Represents a goal."""
|
||||
|
||||
@@ -137,13 +124,32 @@ class Goal(Base):
|
||||
UniqueConstraint('name', 'deleted', name='uniq_goals0name'),
|
||||
table_args(),
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(63), nullable=False)
|
||||
display_name = Column(String(63), nullable=False)
|
||||
efficacy_specification = Column(JSONEncodedList, nullable=False)
|
||||
|
||||
|
||||
class Strategy(Base):
|
||||
"""Represents a strategy."""
|
||||
|
||||
__tablename__ = 'strategies'
|
||||
__table_args__ = (
|
||||
UniqueConstraint('uuid', name='uniq_strategies0uuid'),
|
||||
UniqueConstraint('name', 'deleted', name='uniq_strategies0name'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(63), nullable=False)
|
||||
display_name = Column(String(63), nullable=False)
|
||||
goal_id = Column(Integer, ForeignKey('goals.id'), nullable=False)
|
||||
parameters_spec = Column(JSONEncodedDict, nullable=True)
|
||||
|
||||
goal = orm.relationship(Goal, foreign_keys=goal_id, lazy=None)
|
||||
|
||||
|
||||
class AuditTemplate(Base):
|
||||
"""Represents an audit template."""
|
||||
|
||||
@@ -163,6 +169,9 @@ class AuditTemplate(Base):
|
||||
version = Column(String(15), nullable=True)
|
||||
scope = Column(JSONEncodedList)
|
||||
|
||||
goal = orm.relationship(Goal, foreign_keys=goal_id, lazy=None)
|
||||
strategy = orm.relationship(Strategy, foreign_keys=strategy_id, lazy=None)
|
||||
|
||||
|
||||
class Audit(Base):
|
||||
"""Represents an audit."""
|
||||
@@ -172,7 +181,7 @@ class Audit(Base):
|
||||
UniqueConstraint('uuid', name='uniq_audits0uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36))
|
||||
audit_type = Column(String(20))
|
||||
state = Column(String(20), nullable=True)
|
||||
@@ -183,24 +192,8 @@ class Audit(Base):
|
||||
strategy_id = Column(Integer, ForeignKey('strategies.id'), nullable=True)
|
||||
scope = Column(JSONEncodedList, nullable=True)
|
||||
|
||||
|
||||
class Action(Base):
|
||||
"""Represents an action."""
|
||||
|
||||
__tablename__ = 'actions'
|
||||
__table_args__ = (
|
||||
UniqueConstraint('uuid', name='uniq_actions0uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36), nullable=False)
|
||||
action_plan_id = Column(Integer, ForeignKey('action_plans.id'),
|
||||
nullable=False)
|
||||
# only for the first version
|
||||
action_type = Column(String(255), nullable=False)
|
||||
input_parameters = Column(JSONEncodedDict, nullable=True)
|
||||
state = Column(String(20), nullable=True)
|
||||
next = Column(String(36), nullable=True)
|
||||
goal = orm.relationship(Goal, foreign_keys=goal_id, lazy=None)
|
||||
strategy = orm.relationship(Strategy, foreign_keys=strategy_id, lazy=None)
|
||||
|
||||
|
||||
class ActionPlan(Base):
|
||||
@@ -211,7 +204,7 @@ class ActionPlan(Base):
|
||||
UniqueConstraint('uuid', name='uniq_action_plans0uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36))
|
||||
first_action_id = Column(Integer)
|
||||
audit_id = Column(Integer, ForeignKey('audits.id'), nullable=False)
|
||||
@@ -219,6 +212,31 @@ class ActionPlan(Base):
|
||||
state = Column(String(20), nullable=True)
|
||||
global_efficacy = Column(JSONEncodedDict, nullable=True)
|
||||
|
||||
audit = orm.relationship(Audit, foreign_keys=audit_id, lazy=None)
|
||||
strategy = orm.relationship(Strategy, foreign_keys=strategy_id, lazy=None)
|
||||
|
||||
|
||||
class Action(Base):
|
||||
"""Represents an action."""
|
||||
|
||||
__tablename__ = 'actions'
|
||||
__table_args__ = (
|
||||
UniqueConstraint('uuid', name='uniq_actions0uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36), nullable=False)
|
||||
action_plan_id = Column(Integer, ForeignKey('action_plans.id'),
|
||||
nullable=False)
|
||||
# only for the first version
|
||||
action_type = Column(String(255), nullable=False)
|
||||
input_parameters = Column(JSONEncodedDict, nullable=True)
|
||||
state = Column(String(20), nullable=True)
|
||||
next = Column(String(36), nullable=True)
|
||||
|
||||
action_plan = orm.relationship(
|
||||
ActionPlan, foreign_keys=action_plan_id, lazy=None)
|
||||
|
||||
|
||||
class EfficacyIndicator(Base):
|
||||
"""Represents an efficacy indicator."""
|
||||
@@ -228,7 +246,7 @@ class EfficacyIndicator(Base):
|
||||
UniqueConstraint('uuid', name='uniq_efficacy_indicators0uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(63))
|
||||
description = Column(String(255), nullable=True)
|
||||
@@ -237,6 +255,9 @@ class EfficacyIndicator(Base):
|
||||
action_plan_id = Column(Integer, ForeignKey('action_plans.id'),
|
||||
nullable=False)
|
||||
|
||||
action_plan = orm.relationship(
|
||||
ActionPlan, foreign_keys=action_plan_id, lazy=None)
|
||||
|
||||
|
||||
class ScoringEngine(Base):
|
||||
"""Represents a scoring engine."""
|
||||
@@ -247,7 +268,7 @@ class ScoringEngine(Base):
|
||||
UniqueConstraint('name', 'deleted', name='uniq_scoring_engines0name'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
uuid = Column(String(36), nullable=False)
|
||||
name = Column(String(63), nullable=False)
|
||||
description = Column(String(255), nullable=True)
|
||||
|
||||
Reference in New Issue
Block a user