feat:preserve tag order after renaming

This commit is contained in:
hxy7yx
2026-07-19 19:40:51 -07:00
parent b400f170cd
commit 11f1269b3b
2 changed files with 34 additions and 9 deletions
+11 -1
View File
@@ -29,6 +29,7 @@ typedef struct tag_elem {
char *name;
neu_datatag_t *tag;
uint64_t order;
UT_hash_handle hh;
} tag_elem_t;
@@ -37,15 +38,22 @@ struct neu_group {
char *name;
tag_elem_t *tags;
uint64_t next_tag_order;
uint32_t interval;
int64_t timestamp;
pthread_mutex_t mtx;
};
static int tag_order_cmp(tag_elem_t *left, tag_elem_t *right);
static UT_array *to_array(tag_elem_t *tags);
static void update_timestamp(neu_group_t *group);
static int tag_order_cmp(tag_elem_t *left, tag_elem_t *right)
{
return (left->order > right->order) - (left->order < right->order);
}
neu_group_t *neu_group_new(const char *name, uint32_t interval)
{
neu_group_t *group = calloc(1, sizeof(neu_group_t));
@@ -166,6 +174,7 @@ int neu_group_add_tag(neu_group_t *group, const neu_datatag_t *tag)
return NEU_ERR_EINTERNAL;
}
el->order = group->next_tag_order++;
HASH_ADD_STR(group->tags, name, el);
update_timestamp(group);
pthread_mutex_unlock(&group->mtx);
@@ -232,7 +241,8 @@ int neu_group_rename_tag(neu_group_t *group, const char *old_name,
el->name = new_el_name;
free(el->tag->name);
el->tag->name = new_tag_name;
HASH_ADD_STR(group->tags, name, el);
HASH_ADD_KEYPTR_INORDER(hh, group->tags, el->name, strlen(el->name), el,
tag_order_cmp);
update_timestamp(group);
ret = NEU_ERR_SUCCESS;
+23 -8
View File
@@ -826,24 +826,39 @@ class TestTag:
assert NEU_ERR_TAG_DECIMAL_INVALID == response.json()['error']
assert 1 == response.json()['index']
@description(given="an existing tag", when="renaming to a new name", then="successfully renamed")
@description(given="three existing tags", when="renaming the middle tag", then="successfully renamed without changing tag order")
def test_rename_tag_success(self):
tag = [{"name": "rename_test_tag", "address": "1!400001",
"attribute": NEU_TAG_ATTRIBUTE_RW, "type": NEU_TYPE_INT16}]
api.add_tags(node="modbus-tcp", group="group1", tags=tag)
tags = [
{"name": "rename_first_tag", "address": "1!400001",
"attribute": NEU_TAG_ATTRIBUTE_RW, "type": NEU_TYPE_INT16},
{"name": "rename_middle_tag", "address": "1!400002",
"attribute": NEU_TAG_ATTRIBUTE_RW, "type": NEU_TYPE_INT16},
{"name": "rename_last_tag", "address": "1!400003",
"attribute": NEU_TAG_ATTRIBUTE_RW, "type": NEU_TYPE_INT16},
]
api.add_tags(node="modbus-tcp", group="group1", tags=tags)
response = api.rename_tag(node="modbus-tcp", group="group1",
old_name="rename_test_tag", new_name="renamed_tag")
old_name="rename_middle_tag",
new_name="renamed_middle_tag")
assert 200 == response.status_code
assert NEU_ERR_SUCCESS == response.json()['error']
response = api.get_tags(node="modbus-tcp", group="group1")
assert 200 == response.status_code
tag_names = [t['name'] for t in response.json()['tags']]
assert "renamed_tag" in tag_names
assert "rename_test_tag" not in tag_names
renamed_tags = [
name for name in tag_names
if name in {"rename_first_tag", "renamed_middle_tag",
"rename_last_tag"}
]
assert ["rename_first_tag", "renamed_middle_tag",
"rename_last_tag"] == renamed_tags
assert "rename_middle_tag" not in tag_names
api.del_tags(node="modbus-tcp", group="group1", tags=["renamed_tag"])
api.del_tags(node="modbus-tcp", group="group1",
tags=["rename_first_tag", "renamed_middle_tag",
"rename_last_tag"])
@description(given="an existing tag", when="renaming to a name that already exists", then="fail with conflict error")
def test_rename_tag_conflict(self):