LCOV - code coverage report
Current view: top level - src/tools/kdb - mergehelper.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 28 65 43.1 %
Date: 2019-09-12 12:28:41 Functions: 6 11 54.5 %

          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 <iostream>
      10             : #include <vector>
      11             : 
      12             : #include <cmdline.hpp>
      13             : #include <keysetio.hpp>
      14             : 
      15             : #include <mergehelper.hpp>
      16             : #include <merging/automergeconfiguration.hpp>
      17             : #include <merging/importmergeconfiguration.hpp>
      18             : #include <merging/interactivemergestrategy.hpp>
      19             : #include <merging/onesidemergeconfiguration.hpp>
      20             : #include <merging/overwritemergeconfiguration.hpp>
      21             : 
      22             : using namespace kdb;
      23             : using namespace kdb::tools::merging;
      24             : using namespace std;
      25             : 
      26         160 : MergeHelper::MergeHelper ()
      27             : {
      28             :         // TODO: this is just a quickfix, find a better solution
      29             :         // without eager instantiating all the strategies. Maybe even automatically
      30             :         // discover all available strategies
      31             :         // comment markus: the factory could be part of libtools
      32         320 :         configurationMap.insert (make_pair ("preserve", new AutoMergeConfiguration ()));
      33             : 
      34         320 :         configurationMap.insert (make_pair ("ours", new OneSideMergeConfiguration (OURS)));
      35         240 :         configurationMap.insert (make_pair ("theirs", new OneSideMergeConfiguration (THEIRS)));
      36             : 
      37             :         // primarily used for import
      38         320 :         configurationMap.insert (make_pair ("cut", new OverwriteMergeConfiguration (THEIRS)));
      39         320 :         configurationMap.insert (make_pair ("import", new ImportMergeConfiguration ()));
      40          80 : }
      41             : 
      42         240 : MergeHelper::~MergeHelper ()
      43             : {
      44         160 :         vector<MergeConfiguration *> configurations = getAllConfigurations ();
      45         720 :         for (auto & configuration : configurations)
      46             :         {
      47         400 :                 delete (configuration);
      48             :         }
      49          80 : }
      50             : 
      51          80 : vector<MergeConfiguration *> MergeHelper::getAllConfigurations ()
      52             : {
      53          80 :         vector<MergeConfiguration *> result;
      54         640 :         for (auto & elem : configurationMap)
      55             :         {
      56         400 :                 result.push_back ((elem).second);
      57             :         }
      58             : 
      59          80 :         return result;
      60             : }
      61             : 
      62           0 : string MergeHelper::getConfigurationList ()
      63             : {
      64           0 :         ostringstream oss;
      65           0 :         for (auto & elem : configurationMap)
      66             :         {
      67           0 :                 oss << (elem).first << ",";
      68             :         }
      69             : 
      70           0 :         return oss.str ();
      71             : }
      72             : 
      73          80 : void MergeHelper::configureMerger (Cmdline const & cl, ThreeWayMerge & merger)
      74             : {
      75          80 :         if (cl.interactive)
      76             :         {
      77           0 :                 merger.addConflictStrategy (new InteractiveMergeStrategy (cin, cout));
      78           0 :                 cout << "Chose interactive merge" << endl;
      79             :         }
      80             :         else
      81             :         {
      82         240 :                 if (configurationMap.find (cl.strategy) == configurationMap.end ())
      83             :                 {
      84           0 :                         throw invalid_argument ("'" + cl.strategy +
      85           0 :                                                 "' is not a valid strategy. Valid strategies are: " + getConfigurationList ());
      86             :                 }
      87             : 
      88          80 :                 MergeConfiguration * configuration = configurationMap[cl.strategy];
      89          80 :                 configuration->configureMerger (merger);
      90             :         }
      91          80 : }
      92             : 
      93          80 : void MergeHelper::reportResult (Cmdline const & cl, MergeResult & result, ostream & out, ostream & err)
      94             : {
      95          80 :         if (!result.hasConflicts ())
      96             :         {
      97          80 :                 if (cl.verbose)
      98             :                 {
      99           0 :                         out << result.getMergedKeys ().size () << " keys in the result" << endl;
     100           0 :                         out << result.getNumberOfEqualKeys () << " keys were equal" << endl;
     101           0 :                         out << result.getNumberOfResolvedKeys () << " keys were resolved" << endl;
     102             :                 }
     103             :         }
     104             :         else
     105             :         {
     106           0 :                 KeySet conflicts = result.getConflictSet ();
     107             : 
     108           0 :                 err << conflicts.size () << " conflicts were detected that could not be resolved automatically:" << endl;
     109           0 :                 conflicts.rewind ();
     110           0 :                 Key current;
     111           0 :                 while ((current = conflicts.next ()))
     112             :                 {
     113           0 :                         string ourConflict = current.getMeta<string> ("conflict/operation/our");
     114           0 :                         string theirConflict = current.getMeta<string> ("conflict/operation/their");
     115             : 
     116           0 :                         err << current << endl;
     117           0 :                         err << "ours: " << ourConflict << ", theirs: " << theirConflict << endl;
     118           0 :                         err << endl;
     119             :                 }
     120             : 
     121           0 :                 err << "Merge unsuccessful." << endl;
     122             :         }
     123          80 : }
     124             : 
     125             : 
     126           0 : KeySet prependNamespace (KeySet const & resultKeys, std::string const & ns)
     127             : {
     128           0 :         KeySet ret;
     129           0 :         for (auto const & k : resultKeys)
     130             :         {
     131           0 :                 ret.append (prependNamespace (k, ns));
     132             :         }
     133           0 :         return ret;
     134             : }
     135             : 
     136           0 : Key prependNamespace (Key const & root, std::string const & ns)
     137             : {
     138           0 :         Key ret = root.dup ();
     139           0 :         if (ret.isCascading ())
     140             :         {
     141           0 :                 ret.setName (ns + root.getName ());
     142             :         }
     143           0 :         return ret;
     144             : }
     145             : 
     146           0 : void applyMeta (KeySet & imported, KeySet const & base)
     147             : {
     148           0 :         for (auto k : imported)
     149             :         {
     150           0 :                 Key b = base.lookup (k, 0);
     151           0 :                 if (b)
     152             :                 {
     153             :                         k.copyAllMeta (b);
     154             :                 }
     155             :         }
     156        7164 : }

Generated by: LCOV version 1.13