Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
kdb: add elektraDiffUndo function
Browse files Browse the repository at this point in the history
  • Loading branch information
atmaxinger committed May 29, 2023
1 parent ed6f0fb commit 90bfcd9
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 16 deletions.
11 changes: 11 additions & 0 deletions src/bindings/cpp/include/elektradiff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class ElektraDiff
inline static ElektraDiff calculateDiff (const KeySet & newKeys, const KeySet & oldKeys, const std::string & parentKeyName);
inline static ElektraDiff calculateDiff (const KeySet & newKeys, const KeySet & oldKeys, const Key & parentKey);

inline void undo (KeySet & ks);

// reference handling

inline void operator++ (int) const;
Expand Down Expand Up @@ -168,6 +170,15 @@ inline ElektraDiff ElektraDiff::calculateDiff (const KeySet & newKeys, const Key
return ElektraDiff (diff);
}

/**
* Undo the changes represented in this diff
* @param ks the keyset where the changs should be undone
*/
inline void ElektraDiff::undo (KeySet & ks)
{
ckdb::elektraDiffUndo (diff, ks.getKeySet());
}

/**
* @copydoc elektraDiffIncRef
*/
Expand Down
2 changes: 2 additions & 0 deletions src/include/kdbdiff.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ void elektraDiffRemoveKey (ElektraDiff * ksd, Key * toRemove);
ElektraDiff * elektraDiffCut (ElektraDiff * original, const Key * cutpoint);
ElektraDiff * elektraDiffDup (const ElektraDiff * original);

void elektraDiffUndo (ElektraDiff * ksd, KeySet * ks);

uint16_t elektraDiffIncRef (ElektraDiff * ksd);
uint16_t elektraDiffDecRef (ElektraDiff * ksd);
uint16_t elektraDiffGetRef (ElektraDiff * ksd);
Expand Down
22 changes: 22 additions & 0 deletions src/libs/elektra/diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,28 @@ KeySet * elektraDiffGetModifiedMetaKeys (const ElektraDiff * ksd, Key * key)
return modifiedKeys;
}

/**
* Undos the changes that are presented in the diff.
* - Added keys get removed from @p ks
* - Removed keys get added back to @p ks,
* - Modified keys will get their old values and meta data in @p ks
*
* @param ksd the diff
* @param ks the keyset that shall be undone
*/
void elektraDiffUndo (ElektraDiff * ksd, KeySet * ks)
{
for (elektraCursor i = 0; i < ksGetSize (ksd->addedKeys); i++)
{
Key * toRemove = ksAtCursor (ksd->addedKeys, i);
Key * key = ksLookup (ks, toRemove, KDB_O_POP);
keyDel (key);
}

ksAppend (ks, ksd->modifiedKeys);
ksAppend (ks, ksd->removedKeys);
}

/**
* @brief Increment the reference counter of a ElektraDiff object
*
Expand Down
1 change: 1 addition & 0 deletions src/libs/elektra/symbols.map
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ libelektra_1.0 {
elektraDiffRemoveKey;
elektraDiffCut;
elektraDiffAppend;
elektraDiffUndo;
};

libelektraprivate_1.0 {
Expand Down
17 changes: 1 addition & 16 deletions src/libs/record/record.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,19 +507,7 @@ bool elektraRecordUndo (KDB * handle, KDB * sessionStorageHandle, Key * parentKe
goto cleanup;
}

KeySet * keysToRemove = elektraDiffGetAddedKeys (undoDiff);
KeySet * keysToModify = elektraDiffGetModifiedKeys (undoDiff);
KeySet * keysToAdd = elektraDiffGetRemovedKeys (undoDiff);

for (elektraCursor i = 0; i < ksGetSize (keysToRemove); i++)
{
Key * toRemove = ksAtCursor (keysToRemove, i);
Key * key = ksLookup (ks, toRemove, KDB_O_POP);
keyDel (key);
}

ksAppend (ks, keysToModify);
ksAppend (ks, keysToAdd);
elektraDiffUndo (undoDiff, ks);

// Disable session recording for now
Key * activeKey = ksLookupByName (handle->global, ELEKTRA_RECORD_CONFIG_ACTIVE_KEY, KDB_O_POP);
Expand All @@ -546,9 +534,6 @@ bool elektraRecordUndo (KDB * handle, KDB * sessionStorageHandle, Key * parentKe
ksAppendKey (handle->global, activeKey);
}

ksDel (keysToRemove);
ksDel (keysToModify);
ksDel (keysToAdd);
ksDel (ks);

if (!successful)
Expand Down
36 changes: 36 additions & 0 deletions tests/ctest/test_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,40 @@ static void test_elektraDiffDup_shouldDuplicate (void)
keyDel (parentKey);
}

static void test_elektraDiffUndo (void)
{
printf ("Test %s\n", __func__);

// Arrange
KeySet * keyset = ksNew (1,
keyNew ("user:/added", KEY_VALUE, "1234", KEY_END),
keyNew ("user:/modified", KEY_VALUE, "modified value", KEY_END),
KS_END);

Key * parentKey = keyNew ("/", KEY_END);

ElektraDiff * diff = elektraDiffNew (
ksNew (1, keyNew ("user:/added", KEY_VALUE, "1234", KEY_END), KS_END),
ksNew (1, keyNew ("user:/removed", KEY_VALUE, "removed key", KEY_END), KS_END),
ksNew (1, keyNew ("user:/modified", KEY_VALUE, "old value", KEY_END), KS_END),
ksNew (1, keyNew ("user:/modified", KEY_VALUE, "new value", KEY_END), KS_END),
parentKey
);

// Act
elektraDiffUndo (diff, keyset);


// Assert
succeed_if_fmt (ksGetSize (keyset) == 2, "expected 2 keys, got %zu", ksGetSize (keyset));
succeed_if_keyset_contains_key_with_string (keyset, "user:/removed", "removed key");
succeed_if_keyset_contains_key_with_string (keyset, "user:/modified", "old value");

ksDel (keyset);
keyDel (parentKey);
elektraDiffDel (diff);
}

int main (int argc, char ** argv)
{
printf ("DIFF TESTS\n");
Expand Down Expand Up @@ -919,6 +953,8 @@ int main (int argc, char ** argv)

test_elektraDiffDup_shouldDuplicate ();

test_elektraDiffUndo ();

elektraDiffDel (demoDiff);

printf ("\ntest_diff RESULTS: %d test(s) done. %d error(s).\n", nbTest, nbError);
Expand Down

0 comments on commit 90bfcd9

Please sign in to comment.