Skip to content

Commit 07f4f61

Browse files
committed
Add detector for names with trailing slashes
Collections and data object names with trailing slashes cause problems: irods/irods#3892 This adds a detector, and extracts the output processing logic for name-related issues to a common inner function in the detector.
1 parent 627c810 commit 07f4f61

File tree

3 files changed

+53
-27
lines changed

3 files changed

+53
-27
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This script checks the iRODS ICAT database for unexpected issues, specifically:
77
- Object names that contain characters which are not handled correctly on XML-based clients,
88
such as the python-irods-client (See https://github.com/irods/irods/issues/4132 for details).
99
- Data objects with empty names
10+
- Collection and data object names with trailing slashes (See https://github.com/irods/irods/issues/3892)
1011
- Files in vaults that have a directory name which is inconsistent with the collection name
1112
- Hard links: multiple data objects refer to the same physical file
1213
- Duplicate replica: multiple replica entries for the same file

icat_tools/dbcheck_outputprocessors.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ def output_item(self, check, values):
7373
"Name with characters that iRODS processes incorrectly for " +
7474
values['check_name'])
7575
self._print_report_column_table(values['report_columns'])
76+
elif values['type'] == 'trailing_slash':
77+
self._prnln(
78+
"Name with trailing slash for " +
79+
values['check_name'])
80+
self._print_report_column_table(values['report_columns'])
7681
else:
7782
self.exit_error("Error: unknown output item type for names check: {}".format(
7883
values['type']))
@@ -149,7 +154,7 @@ def output_item(self, check, values):
149154
[check, values['object_name'], values['number_replicas'], values['min_replicas']])
150155

151156
elif check == 'names':
152-
if values['type'] == 'empty_name' or values['type'] == 'buggy_characters':
157+
if values['type'] in ['empty_name','buggy_characters','trailing_slash']:
153158
self.writer.writerow([check, values['type'], values['check_name']] +
154159
self._column_value_to_list(values['report_columns']))
155160
else:

icat_tools/detectors/nameissue_detector.py

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,41 @@ def _check_name_buggy_characters(self, table, name, report_columns):
5050
cursor.execute(query)
5151
return cursor
5252

53+
def _check_name_trailing_slash(self, table, name, report_columns):
54+
query = "SELECT {} FROM {} WHERE {} != '/' AND {} LIKE '%/' {}".format( ",".join(report_columns), table, name, name, self._get_prefix_condition(table))
55+
cursor = self.connection.cursor("{}._check_name_trailing_slash".format(self.get_name()))
56+
cursor.execute(query)
57+
return cursor
58+
5359
def run(self):
5460
issue_found = False
61+
62+
def _do_output(type_name, report_columns, query_result):
63+
"""Internal function for translating query results of a check to a generic
64+
output dictionary and feeding it to the output processor. Also translates
65+
collection IDs to collection names for readability."""
66+
nonlocal issue_found
67+
68+
for row in query_result:
69+
output = {'type': type_name, 'check_name' : check_name, 'report_columns': {}}
70+
column_num = 0
71+
for report_column in report_columns:
72+
if str(report_column) == 'coll_id':
73+
coll_name = utils.get_collection_name(
74+
self.connection, str(row[column_num]))
75+
if coll_name is not None:
76+
output['report_columns']['Collection name'] = coll_name
77+
else:
78+
output['report_columns'][str(report_column)] = str(
79+
row[column_num])
80+
column_num = column_num + 1
81+
82+
self.output_item(output)
83+
issue_found = True
84+
85+
query_result.close()
86+
return issue_found
87+
5588
for check_name, check_params in self._get_name_check_data():
5689
if self.args.v:
5790
self.print_progress("Running empty name test for: " + check_name)
@@ -60,16 +93,18 @@ def run(self):
6093
check_params['table'],
6194
check_params['name'],
6295
check_params['report_columns'])
63-
for row in result_empty:
64-
output = {'type': 'empty_name', 'check_name' : check_name, 'report_columns': {}}
65-
column_num = 0
66-
for report_column in check_params['report_columns']:
67-
output['report_columns'][str(report_column)] = str(
68-
row[column_num])
69-
column_num = column_num + 1
70-
self.output_item(output)
71-
issue_found = True
72-
result_empty.close()
96+
_do_output("empty_name", check_params['report_columns'], result_empty)
97+
98+
99+
if check_name in ["data object", "collection"]:
100+
if self.args.v:
101+
self.print_progress("Running trailing slash test for: " + check_name)
102+
103+
result_trailing_slash = self._check_name_trailing_slash(
104+
check_params['table'],
105+
check_params['name'],
106+
check_params['report_columns'])
107+
_do_output("trailing_slash", check_params['report_columns'], result_trailing_slash)
73108

74109
if self.args.v:
75110
self.print_progress("Running problematic character name test for: " + check_name)
@@ -78,21 +113,6 @@ def run(self):
78113
check_params['table'],
79114
check_params['name'],
80115
check_params['report_columns'])
81-
for row in result_buggy_characters:
82-
output = {'type': 'buggy_characters', 'check_name' : check_name, 'report_columns': {}}
83-
column_num = 0
84-
for report_column in check_params['report_columns']:
85-
if str(report_column) == 'coll_id':
86-
coll_name = utils.get_collection_name(
87-
self.connection, str(row[column_num]))
88-
if coll_name is not None:
89-
output['report_columns']['Collection name'] = coll_name
90-
else:
91-
output['report_columns'][str(report_column)] = str(
92-
row[column_num])
93-
column_num = column_num + 1
94-
self.output_item(output)
95-
issue_found = True
96-
result_buggy_characters.close()
116+
_do_output("buggy_characters", check_params['report_columns'], result_buggy_characters)
97117

98118
return issue_found

0 commit comments

Comments
 (0)