libelektra
libelektra copied to clipboard
[CM T0] kdb mv (move single key, non-recursive) silently deletes child-keys
Steps to Reproduce the Problem
kdb set user:/key "Some value"
kdb set user:/key/child "Some child value"
kdb ls user:/
#> user:/key
#> user:/key/child
kdb mv user:/key user:/otherkey
kdb ls user:/
#> user:/otherkey
Expected Result
Either
kdb ls user:/
#> user:/key/child
#> user:/otherkey
or an error.
Actual Result
The key user:/key/child gets deleted.
kdb ls user:/
#> user:/otherkey
System Information
- Elektra Version: KDB_VERSION: 0.9.4, SO_VERSION: 5
- Operating System or Docker Container? Docker container, Ubuntu Focal
Thank you for reporting this problem! This looks like a severe problem in kdb mv. We should definitely add a testcase for this.
[CM T0]
My colleague @Gratla and I want to work on this issue.
I reproduced this issue with the following steps:
$ kdb set user:/foo bar
Create a new key user:/foo with string "bar"
$ kdb set user:/foo/two bar2
Create a new key user:/foo/two with string "bar2"
$ kdb ls user:/
user:/foo
user:/foo/two
$ kdb mv user:/foo user:/new
$ kdb ls user:/
user:/new
What is the desired/intended behaviour of mv?
I would propose to move all sub-keys together with the parent key.
I think the bug is located in the file /libelektra/src/tools/kdb/mv.cpp. After a short look I think the bug is located in the following code-snippet, but we need to re-check it as we work on it:
if (cl.recursive)
{
while ((k = oldConf.next ()))
{
newConf.append (rename_key (k, sourceName, newDirName, cl.verbose));
}
}
else
{
// just rename one key
k = oldConf.next ();
if (k != sourceKey)
{
cerr << "First key found " << k.getName () << " does not exactly match given key " << sourceKey.getName ()
<< ", aborting (use -r to move hierarchy)\n";
return 11;
}
newConf.append (rename_key (k, sourceName, newDirName, cl.verbose));
}
What is the desired/intended behaviour of
mv? I would propose to move all sub-keys together with the parent key.
The manpage says kdb mv moves a single key, but kdb mv -r also moves sub-keys. I think that is reasonable and we can keep it that way.
So the intended behaviour for your example is this
$ kdb set user:/foo bar
Create a new key user:/foo with string "bar"
$ kdb set user:/foo/two bar2
Create a new key user:/foo/two with string "bar2"
$ kdb ls user:/
user:/foo
user:/foo/two
$ kdb mv user:/foo user:/new
$ kdb ls user:/
user:/foo/two
user:/new
$ kdb set user:/foo bar
Create a new key user:/foo with string "bar"
$ kdb ls user:/
user:/foo
user:/foo/two
user:/new
$ kdb mv -r user:/foo user:/other
$ kdb ls user:/
user:/other
user:/other/two
user:/new