Beispiel #1
0
int MergingKDB::synchronize (KeySet & returned, Key & parentKey, ThreeWayMerge & merger)
{
	try
	{
		// write our config
		int ret = KDB::set (returned, parentKey);

		// update our config (if no conflict)
		KDB::get (returned, parentKey);

		return ret;
	}
	catch (KDBException const &)
	{
		// a conflict occurred, see if we can solve it with the merger

		// refresh the key database
		KeySet theirs = returned.dup ();
		KDB::get (theirs, parentKey);

		// try to merge
		MergeResult result = merger.mergeKeySet (MergeTask (BaseMergeKeys (base, parentKey), OurMergeKeys (returned, parentKey),
								    TheirMergeKeys (theirs, parentKey), parentKey));

		if (!result.hasConflicts ())
		{
			// hurray, we solved the issue
			KeySet resultKeys = result.getMergedKeys ();
			int ret = KDB::set (resultKeys, parentKey);
			base = resultKeys;
			return ret;
		}
		else
		{
			// nothing we can do anymore
			KeySet conflictSet = result.getConflictSet ();
			throw MergingKDBException (parentKey, conflictSet);
		}
	}
}
Beispiel #2
0
int MergingKDB::get (KeySet & returned, std::string const & keyname)
{
	int ret = KDB::get (returned, keyname);
	base = returned.dup ();
	return ret;
}
Beispiel #3
0
int MergingKDB::get (KeySet & returned, Key & parentKey)
{
	int ret = KDB::get (returned, parentKey);
	base = returned.dup ();
	return ret;
}
Beispiel #4
0
int EditorCommand::execute (Cmdline const & cl)
{
#ifdef _WIN32
	throw EditorNotAvailable ();
#endif

	int argc = cl.arguments.size ();
	if (argc < 1)
	{
		throw invalid_argument ("wrong number of arguments, 1 needed");
	}
	Key root = cl.createKey (0);

	KeySet ours;
	KDB kdb;
	kdb.get (ours, root);
	KeySet oursToEdit = ours.cut (root);
	KeySet original = oursToEdit.dup ();

	if (cl.strategy == "validate")
	{
		prependNamespace (oursToEdit, cl.ns);
		oursToEdit.cut (prependNamespace (root, cl.ns));
	}

	// export it to file
	string format = cl.format;
	if (argc > 1) format = cl.arguments[1];

	Modules modules;
	PluginPtr plugin = modules.load (format);

	tmpFile ();
	if (cl.verbose) std::cout << "filename set to " << filename << std::endl;
	Key errorKey (root);
	errorKey.setString (filename);

	if (plugin->set (oursToEdit, errorKey) == -1)
	{
		printWarnings (cerr, errorKey);
		printError (cerr, errorKey);
		return 11;
	}

	printWarnings (cerr, errorKey);


	// start editor
	if (cl.verbose) std::cout << "running editor with " << filename << std::endl;
	if (!cl.editor.empty ())
	{
		if (!runEditor (cl.editor, filename))
		{
			std::cerr << "Could not run editor " << cl.editor << std::endl;
			return 12;
		}
	}
	else
	{
		if (!runAllEditors (filename))
		{
			std::cerr << "Could not run any editor, please change /sw/elektra/kdb/#0/current/editor" << std::endl;
			return 12;
		}
	}

	// import from the file
	KeySet importedKeys;
	plugin->get (importedKeys, errorKey);
	importedKeys = importedKeys.cut (root);

	printWarnings (cerr, errorKey);
	printError (cerr, errorKey);

	if (cl.strategy == "validate")
	{
		applyMeta (importedKeys, original);
		kdb.set (importedKeys, root);
		printWarnings (cerr, root);
		return 0;
	}

	ThreeWayMerge merger;
	MergeHelper helper;

	helper.configureMerger (cl, merger);
	MergeResult result = merger.mergeKeySet (
		MergeTask (BaseMergeKeys (oursToEdit, root), OurMergeKeys (oursToEdit, root), TheirMergeKeys (importedKeys, root), root));

	helper.reportResult (cl, result, cout, cerr);

	int ret = 13;
	if (!result.hasConflicts ())
	{
		if (cl.verbose)
		{
			cout << "The merged keyset with strategy " << cl.strategy << " is:" << endl;
			cout << result.getMergedKeys ();
		}

		KeySet resultKeys = result.getMergedKeys ();
		if (cl.verbose) std::cout << "about to write result keys " << resultKeys << std::endl;
		ours.append (resultKeys);
		try
		{
			kdb.set (ours, root);
			if (cl.verbose) std::cout << "successful, cleaning up " << filename << std::endl;
			unlink (filename.c_str ());
			ret = 0;
		}
		catch (KDBException const & e)
		{
			std::cout << "Import of configuration failed with the error:\n";
			std::cout << e.what ();
			std::cout << "\n\n";
			std::cout << "Your changes are not lost." << std::endl;
			std::cout << "Please fix, import and remove \"" << filename << '"' << std::endl;
			ret = 14;
		}
	}
	else
	{
		std::cout << "Import not successful, please import and remove \"" << filename << '"' << std::endl;
	}

	return ret;
}