Skip to content

Commit e6b8038

Browse files
d-w-moorealanking
authored andcommitted
[#392] add iRODSResource properties: parent_name, parent_id, hierarchy_string
1 parent a23f34a commit e6b8038

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

irods/resource.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
class iRODSResource(object):
88

99
def __init__(self, manager, result=None):
10+
self._hierarchy_string = ''
11+
self._parent_name = ''
12+
self._parent_id = ''
1013
'''
1114
self.id = result[Resource.id]
1215
self.name = result[Resource.name]
@@ -38,6 +41,54 @@ def __init__(self, manager, result=None):
3841

3942
self._meta = None
4043

44+
45+
## Cached properties to expose parent id or name regardless whether the DB model is iRODS 4.1- or 4.2+
46+
47+
@property
48+
def parent_id(self):
49+
if self.parent is None:
50+
return None
51+
if self._parent_id == '':
52+
sess = self.manager.sess
53+
if sess.server_version >= (4, 2, 0):
54+
self._parent_id = self.parent
55+
else:
56+
self._parent_id = sess.query(Resource).filter(Resource.name == self.parent).one()[Resource.id]
57+
return int(self._parent_id)
58+
59+
60+
@property
61+
def parent_name(self):
62+
if self.parent is None:
63+
return None
64+
if self._parent_name == '':
65+
sess = self.manager.sess
66+
if sess.server_version < (4, 2, 0):
67+
self._parent_name = self.parent
68+
else:
69+
self._parent_name = sess.query(Resource).filter(Resource.id == self.parent).one()[Resource.name]
70+
return self._parent_name
71+
72+
## Cached property to expose resource hierarchy string
73+
74+
@property
75+
def hierarchy_string(self):
76+
if self._hierarchy_string == '':
77+
self._hierarchy_string = ';'.join(r.name for r in self.hierarchy_as_list_of_resource_objects())
78+
return self._hierarchy_string
79+
80+
## Retrieve chain of parent objects to top level parent
81+
82+
def hierarchy_as_list_of_resource_objects(self):
83+
trace_to_root = [self]
84+
sess = self.manager.sess
85+
r = self.parent_id
86+
while r is not None:
87+
parent = sess.query(Resource).filter(Resource.id == r).one()
88+
trace_to_root.append(iRODSResource(self.manager, parent))
89+
r = trace_to_root[-1].parent_id
90+
return list(reversed(trace_to_root))
91+
4192
@property
4293
def metadata(self):
4394
if not self._meta:

irods/test/resource_test.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#! /usr/bin/env python
2+
from __future__ import absolute_import
3+
import os
4+
import six
5+
import sys
6+
import unittest
7+
8+
from irods.test import helpers
9+
10+
class TestResource(unittest.TestCase):
11+
12+
from helpers import create_simple_resc_hierarchy
13+
14+
def setUp(self):
15+
self.sess = helpers.make_session()
16+
17+
def test_resource_properties_for_parent_and_hierarchy_at_3_levels__392(self):
18+
ses = self.sess
19+
root = "deferred_392"
20+
pt = "pt_392"
21+
leaf = "leaf_392"
22+
root_resc = ses.resources.create(root,"deferred")
23+
try:
24+
# Create two (passthru + storage) hierarchies below the root: ie. pt0;leaf0 and pt1;leaf1
25+
with self.create_simple_resc_hierarchy(pt + "_0", leaf + "_0"), \
26+
self.create_simple_resc_hierarchy(pt + "_1", leaf + "_1"):
27+
try:
28+
# Adopt both passthru's as children under the main root (deferred) node.
29+
ses.resources.add_child(root, pt + "_0")
30+
ses.resources.add_child(root, pt + "_1")
31+
# Now we have two different 3-deep hierarchies (root;pt0;leaf0 and root;pt1;leaf) sharing the same root node.
32+
# Descend each and make sure the relationships hold
33+
for mid in root_resc.children:
34+
hierarchy = [root_resc, mid, mid.children[0]]
35+
parent_resc = None
36+
hier_str = root
37+
# Assert that the hierarchy and parent properties hold at each level, in both tree branches.
38+
for n,resc in enumerate(hierarchy):
39+
if n > 0:
40+
hier_str += ";{}".format(resc.name)
41+
self.assertEqual(resc.parent_id, (None if n == 0 else parent_resc.id))
42+
self.assertEqual(resc.parent_name, (None if n == 0 else parent_resc.name))
43+
self.assertEqual(resc.hierarchy_string, hier_str)
44+
self.assertIs(type(resc.hierarchy_string), str) # type of hierarchy field is string.
45+
if resc.parent is None:
46+
self.assertIs(resc.parent_id, None)
47+
self.assertIs(resc.parent_name, None)
48+
else:
49+
self.assertIn(type(resc.parent_id), six.integer_types) # type of a non-null id field is integer.
50+
self.assertIs(type(resc.parent_name), str) # type of a non-null name field is string.
51+
parent_resc = resc
52+
finally:
53+
ses.resources.remove_child(root, pt + "_0")
54+
ses.resources.remove_child(root, pt + "_1")
55+
finally:
56+
ses.resources.remove(root)
57+
58+
59+
if __name__ == '__main__':
60+
# let the tests find the parent irods lib
61+
sys.path.insert(0, os.path.abspath('../..'))
62+
unittest.main()

0 commit comments

Comments
 (0)