Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions specifyweb/backend/trees/extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,13 @@ def definition_joins(table, depth):
for j in range(depth)
])

def set_fullnames(treedef, null_only=False, node_number_range=None):
def set_fullnames(
treedef,
null_only: bool = False,
node_number_range=None,
include_synonyms: bool = False,
synonyms_only: bool = False,
):
table = treedef.treeentries.model._meta.db_table
depth = treedef.treedefitems.count()
reverse = treedef.fullnamedirection == -1
Expand All @@ -588,29 +594,55 @@ def set_fullnames(treedef, null_only=False, node_number_range=None):
if depth < 1:
return
cursor = connection.cursor()

if synonyms_only:
accepted_filter = "and t0.acceptedid is not null"
elif include_synonyms:
accepted_filter = ""
else:
accepted_filter = "and t0.acceptedid is null"

fullname_sql_expr = fullname_expr(depth, reverse)

diff_condition = (
"and (t0.fullname is null OR t0.fullname <> {expr})".format(
expr=fullname_sql_expr
)
if not null_only
else ""
)

sql = (
"update {table} t0\n"
"{parent_joins}\n"
"{definition_joins}\n"
"set {set_expr}\n"
"where t{root}.parentid is null\n"
"and t0.{table}treedefid = {treedefid}\n"
"and t0.acceptedid is null\n"
"{accepted_filter}\n"
"{null_only}\n"
"{node_number_range}\n"
"{diff_condition}\n"
).format(
root=depth-1,
table=table,
treedefid=treedefid,
set_expr=f"t0.fullname = {fullname_expr(depth, reverse)}",
set_expr=f"t0.fullname = {fullname_sql_expr}",
parent_joins=parent_joins(table, depth),
definition_joins=definition_joins(table, depth),
accepted_filter=accepted_filter,
null_only="and t0.fullname is null" if null_only else "",
node_number_range=f"and t0.nodenumber between {node_number_range[0]} and {node_number_range[1]}" if not (node_number_range is None) else ''
node_number_range=(
f"and t0.nodenumber between {node_number_range[0]} and {node_number_range[1]}"
if node_number_range is not None
else ''
),
diff_condition=diff_condition,
)

logger.debug('fullname update sql:\n%s', sql)
return cursor.execute(sql)
cursor.execute(sql)
return cursor.rowcount

def predict_fullname(table, depth, parentid, defitemid, name, reverse=False):
cursor = connection.cursor()
Expand Down
1 change: 1 addition & 0 deletions specifyweb/backend/trees/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
path('<int:id>/bulk_move/', views.bulk_move),
path('<int:id>/synonymize/', views.synonymize),
path('<int:id>/desynonymize/', views.desynonymize),
path('<int:id>/rebuild_fullname/', views.rebuild_fullname),
path('<int:rankid>/tree_rank_item_count/', views.tree_rank_item_count),
path('<int:parentid>/predict_fullname/', views.predict_fullname),
re_path(r'^(?P<treedef>\d+)/(?P<parentid>\w+)/stats/$', views.tree_stats),
Expand Down
Loading
Loading