Skip to content
This repository has been archived by the owner on Jul 17, 2018. It is now read-only.

Commit

Permalink
ARIA-158 Restore support for relationship ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
mxmrlv committed Apr 27, 2017
1 parent 5bc28b6 commit 1f3e7ff
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
8 changes: 5 additions & 3 deletions aria/modeling/relationship.py
Expand Up @@ -14,7 +14,6 @@
# limitations under the License.

# pylint: disable=invalid-name, redefined-outer-name

from sqlalchemy.orm import relationship, backref
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy import (
Expand Down Expand Up @@ -161,7 +160,8 @@ def one_to_many(model_class,
child_table,
child_fk=None,
dict_key=None,
back_populates=None):
back_populates=None,
rel_kwargs=None):
"""
Declare a one-to-many relationship property. The property value would be a list or dict of
instances of the child table's model.
Expand All @@ -186,6 +186,8 @@ def one_to_many(model_class,
false to disable
:type back_populates: basestring|bool
"""
rel_kwargs = rel_kwargs or {}
rel_kwargs.setdefault('cascade', 'all')
if back_populates is None:
back_populates = model_class.__tablename__
return _relationship(
Expand All @@ -194,7 +196,7 @@ def one_to_many(model_class,
back_populates=back_populates,
other_fk=child_fk,
dict_key=dict_key,
relationship_kwargs=dict(cascade='all'))
relationship_kwargs=rel_kwargs)


def many_to_one(model_class,
Expand Down
27 changes: 20 additions & 7 deletions aria/modeling/service_instance.py
Expand Up @@ -25,6 +25,7 @@
from sqlalchemy import DateTime
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.orderinglist import ordering_list

from .mixins import InstanceModelMixin
from ..orchestrator import execution_plugin
Expand Down Expand Up @@ -485,12 +486,22 @@ def capabilities(cls):
@declared_attr
def outbound_relationships(cls):
return relationship.one_to_many(
cls, 'relationship', child_fk='source_node_fk', back_populates='source_node')
cls, 'relationship', child_fk='source_node_fk', back_populates='source_node',
rel_kwargs=dict(
order_by='Relationship.source_position',
collection_class=ordering_list('source_position', count_from=0)
)
)

@declared_attr
def inbound_relationships(cls):
return relationship.one_to_many(
cls, 'relationship', child_fk='target_node_fk', back_populates='target_node')
cls, 'relationship', child_fk='target_node_fk', back_populates='target_node',
rel_kwargs=dict(
order_by='Relationship.target_position',
collection_class=ordering_list('target_position', count_from=0)
)
)

# endregion

Expand Down Expand Up @@ -1166,9 +1177,9 @@ class RelationshipBase(InstanceModelMixin):
:vartype properties: {basestring: :class:`Parameter`}
:ivar interfaces: Bundles of operations
:vartype interfaces: {basestring: :class:`Interfaces`}
:ivar source_position: ??
:ivar source_position: The position of the relationship in the outbound relationships.
:vartype source_position: int
:ivar target_position: ??
:ivar target_position: The position of the relationship in the inbound relationships.
:vartype target_position: int
:ivar source_node: Source node
:vartype source_node: :class:`Node`
Expand All @@ -1185,7 +1196,9 @@ class RelationshipBase(InstanceModelMixin):
'target_node_fk',
'target_capability_fk',
'requirement_template_fk',
'relationship_template_fk']
'relationship_template_fk',
'target_position',
'source_position']

# region foreign keys

Expand Down Expand Up @@ -1289,8 +1302,8 @@ def properties(cls):

# endregion

source_position = Column(Integer) # ???
target_position = Column(Integer) # ???
source_position = Column(Integer)
target_position = Column(Integer)

def configure_operations(self):
for interface in self.interfaces.itervalues():
Expand Down
7 changes: 5 additions & 2 deletions tests/modeling/test_mixins.py
Expand Up @@ -155,15 +155,18 @@ def flip_and_assert(node, direction):
"""
assert direction in ('inbound', 'outbound')

relationships = getattr(node, direction + '_relationships')
def get_relationships():
return getattr(node, direction + '_relationships')

relationships = get_relationships()
assert len(relationships) == 2

reversed_relationship = list(reversed(relationships))
assert relationships != reversed_relationship

relationships[:] = reversed_relationship
context.model.node.update(node)
assert relationships == reversed_relationship
assert get_relationships() == reversed_relationship

flip_and_assert(source_node, 'outbound')
flip_and_assert(target_node, 'inbound')
Expand Down

0 comments on commit 1f3e7ff

Please sign in to comment.