Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #include "cmerge.hpp"
10 : #include "kdbmerge.h"
11 : #include "keyset.hpp"
12 : #include <cmdline.hpp>
13 : #include <iostream>
14 : #include <keysetio.hpp>
15 : #include <string>
16 :
17 :
18 78 : CMergeCommand::CMergeCommand ()
19 : {
20 78 : }
21 :
22 156 : CMergeCommand::~CMergeCommand ()
23 : {
24 78 : }
25 :
26 0 : int CMergeCommand::execute (Cmdline const & cl ELEKTRA_UNUSED)
27 : {
28 0 : if (cl.arguments.size () < 4)
29 : {
30 0 : throw invalid_argument ("Wrong number of arguments! At least 4 arguments needed");
31 : }
32 0 : kdb::Key oursRoot = cl.createKey (0);
33 0 : kdb::Key theirsRoot = cl.createKey (1);
34 0 : kdb::Key baseRoot = cl.createKey (2);
35 0 : kdb::Key resultRoot = cl.createKey (3);
36 0 : int strategy = MERGE_STRATEGY_ABORT;
37 0 : if (cl.strategy == "preserve")
38 : {
39 : /** This is here for compatibility. The old merge has preserve as default as defined in cmdline.cpp.
40 : * As cmerge uses the existing functionality it is still default, even though it does not exist in cmerge.
41 : * Default in new merge is abort.
42 : *
43 : * This will be obsolete as soon as cmerge supersedes the old merge.
44 : */
45 : strategy = MERGE_STRATEGY_ABORT;
46 : }
47 0 : else if (cl.strategy == "abort")
48 : {
49 : strategy = MERGE_STRATEGY_ABORT;
50 : }
51 0 : else if (cl.strategy == "our")
52 : {
53 : strategy = MERGE_STRATEGY_OUR;
54 : }
55 0 : else if (cl.strategy == "their")
56 : {
57 : strategy = MERGE_STRATEGY_THEIR;
58 : }
59 : else
60 : {
61 0 : throw invalid_argument ("'" + cl.strategy + "' is not a valid strategy. Valid strategies are: abort, our, their, base");
62 : }
63 :
64 0 : kdb::KeySet ours;
65 0 : kdb::KeySet theirs;
66 0 : kdb::KeySet base;
67 :
68 : {
69 0 : kdb::KDB lkdb;
70 0 : lkdb.get (ours, oursRoot);
71 0 : ours = ours.cut (oursRoot);
72 0 : ours.lookup (oursRoot, 0);
73 0 : if (cl.verbose) std::cout << "we got ours: " << oursRoot << " with keys\n" << ours << std::endl;
74 : }
75 : {
76 0 : kdb::KDB lkdb;
77 0 : lkdb.get (theirs, theirsRoot);
78 0 : theirs = theirs.cut (theirsRoot);
79 0 : ours.lookup (oursRoot, 0);
80 0 : if (cl.verbose) std::cout << "we got theirs: " << theirsRoot << " with keys\n" << theirs << std::endl;
81 : }
82 : {
83 0 : kdb::KDB lkdb;
84 0 : lkdb.get (base, baseRoot);
85 0 : base = base.cut (baseRoot);
86 0 : ours.lookup (oursRoot, 0);
87 0 : if (cl.verbose) std::cout << "we got base: " << baseRoot << " with keys\n" << base << std::endl;
88 : }
89 0 : kdb::KeySet keysAtResultRoot;
90 0 : kdb.get (keysAtResultRoot, resultRoot);
91 0 : kdb::KeySet discard = keysAtResultRoot.cut (resultRoot);
92 0 : if (discard.size () != 0)
93 : {
94 0 : if (cl.force)
95 : {
96 0 : if (cl.verbose)
97 : {
98 0 : std::cout << "will remove " << discard.size () << " keys, because -f was given" << std::endl;
99 : }
100 : }
101 : else
102 : {
103 0 : std::cerr << discard.size () << " keys exist in merge resultpath, will quit. Use -f to override the keys there."
104 : << std::endl;
105 : }
106 : }
107 0 : ckdb::KeySet * c_ours = ours.getKeySet ();
108 0 : ckdb::KeySet * c_theirs = theirs.getKeySet ();
109 0 : ckdb::KeySet * c_base = base.getKeySet ();
110 0 : Key * informationKey = keyNew (0, KEY_END);
111 0 : ckdb::KeySet * c_merge_result = elektraMerge (c_ours, oursRoot.getKey (), c_theirs, theirsRoot.getKey (), c_base,
112 0 : baseRoot.getKey (), resultRoot.getKey (), strategy, informationKey);
113 0 : if (c_merge_result != NULL)
114 : {
115 0 : kdb::KeySet merge_result = c_merge_result;
116 0 : if (keysAtResultRoot.append (merge_result) < 0)
117 : {
118 : return 1;
119 : }
120 0 : if (kdb.set (keysAtResultRoot, resultRoot) < 0)
121 : {
122 : return 1;
123 : }
124 0 : return 0;
125 : }
126 : else
127 : {
128 : return 1;
129 : }
130 7164 : }
|