예제 #1
0
string rebasePath(const Key& key, const Key& oldParent,
		const Key& newParent)
{
	string oldKeyPath = key.getName ();

	Key actualOldParent = oldParent.dup();
	if (oldParent.getNamespace() == "/")
	{
		actualOldParent.setName(key.getNamespace() + oldParent.getName());
	}

	Key actualNewParent = newParent.dup();
	if (newParent.getNamespace() == "/")
	{
		actualNewParent.setName(key.getNamespace() + newParent.getName());
	}

	if (!key.isBelowOrSame(actualOldParent)) throw InvalidRebaseException(
			"the supplied key " +
			key.getName() +
			" is not below the old parent " +
			actualOldParent.getName());

	string relativePath = oldKeyPath.substr (actualOldParent.getName().length (),
			oldKeyPath.length ());
	string newPath = actualNewParent.getName () + relativePath;

	return newPath;
}
예제 #2
0
Key commonKeyName (Key key1, Key key2)
{
	// do not let removed namespaces escape
	key1 = key1.dup();
	key2 = key2.dup();

	if (key1.isBelowOrSame(key2)) return key2;
	if (key2.isBelowOrSame(key1)) return key1;

	if (key1.getNamespace() != key2.getNamespace())
	{
		removeNamespace(key1);
		removeNamespace(key2);
	}

	Key ret(key1.getNamespace(), KEY_END);
	for (auto it1 = ++key1.begin(), it2 = ++key2.begin();
	     it1 != key1.end() && it2 != key2.end();
	     ++it1, ++it2)
	{
		if (*it1 != *it2) break;
		ret.addBaseName(*it1);
	}
	return ret;

}
예제 #3
0
void GlobalPlugins::serialize (kdb::KeySet & ret)
{
	// transform to suitable data structure
	std::map<std::shared_ptr<Plugin>, Placements> pp;
	for (auto const & placements : plugins)
	{
		for (auto const & plugin : placements.second)
		{
			std::istringstream ss (plugin->lookupInfo ("status"));
			std::string status;
			bool isglobal = false;
			while (ss >> status)
			{
				if (status == "global") isglobal = true;
			}

			if (!isglobal)
			{
				throw NoGlobalPlugin (plugin->name ());
			}

			pp[plugin].addPlacement (placements.first);
		}
	}

	ret.append (Key ("system/elektra/globalplugins", KEY_VALUE, "", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/placements", KEY_VALUE, "", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/placements/set", KEY_VALUE, "presetstorage precommit postcommit",
			 KEY_END));
	ret.append (
		Key ("system/elektra/globalplugins/postcommit/user/placements/get", KEY_VALUE, "pregetstorage postgetstorage", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/placements/error", KEY_VALUE, "prerollback postrollback", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/plugins", KEY_VALUE, "", KEY_END));
	Key i ("system/elektra/globalplugins/postcommit/user/plugins/#0", KEY_END);
	for (auto const & plugin : pp)
	{
		i.setString (plugin.first->name ());
		ret.append (i.dup ());
		Key placements (i.dup ());
		placements.addBaseName ("placements");
		ret.append (placements);

		ret.append (g (placements, "get", plugin.second.get));
		ret.append (g (placements, "set", plugin.second.set));
		ret.append (g (placements, "error", plugin.second.error));

		serializeConf (ret, Key (i.getName () + "/config", KEY_VALUE, "", KEY_END), plugin.first->getConfig ());
		ckdb::elektraArrayIncName (*i);
	}
	ret.append (Key ("system/elektra/globalplugins/postrollback", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/precommit", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/pregetstorage", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postgetstorage", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/presetstorage", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/prerollback", KEY_VALUE, "list", KEY_END));
}
예제 #4
0
void SpecMountpointReader::processKey (Key const & ck)
{
	Key k (ck);
	k.rewindMeta ();
	Key m;
	while ((m = k.nextMeta ()))
	{
		std::string const & cn = "config/needs";
		if (startsWith (m.getName (), cn))
		{
			Key bKey = m.dup ();
			bKey.setName ("user" + bKey.getName ().substr (cn.length ()));
			backendConfig.append (bKey);
		}
		else if (m.getName () == "infos/plugins")
		{
			bb.addPlugins (parseArguments (m.getString ()));
		}
		else if (m.getName () == "infos/needs")
		{
			bb.needPlugin (m.getString ());
		}
		else if (m.getName () == "infos/recommends")
		{
			bb.recommendPlugin (m.getString ());
		}
		else if (isToBeIgnored (m.getName ()))
		{
		}
		else
		{
			bb.needMetadata (m.getName ());
		}
	}
}
예제 #5
0
SpecBackendBuilder SpecMountpointReader::readMountpointSpecification (KeySet const & cks)
{
	ks = cks;
	mp = ks.head ().dup ();

	Key rmp (mp.dup ());
	helper::removeNamespace (rmp);

	bb.setMountpoint (rmp, mountConf);

	processKey (mp);
	bb.nodes++; // count mp

	ks.lookup (mp, KDB_O_POP);

	ks.rewind (); // we need old fashioned loop, because it can handle ks.cut during iteration
	for (Key k = ks.next (); k; k = ks.next ())
	{
		// search for mountpoint
		Key m = k.getMeta<const Key> ("mountpoint");
		if (m)
		{
			SpecMountpointReader smr (backends, bbi);
			backends[k] = smr.readMountpointSpecification (ks.cut (k));
			continue;
		}

		processKey (k);
		bb.nodes++;
	}

	bb.setBackendConfig (backendConfig);
	bb.useConfigFile (mp.getMeta<std::string> ("mountpoint"));
	return bb;
}
예제 #6
0
Key rebaseKey(const Key& key, const Key& oldParent,
		const Key& newParent)
{
	string newPath = rebasePath (key, oldParent, newParent);
	Key result = key.dup ();
	result.setName (newPath);
	return result;
}
예제 #7
0
/**
 * This constructor creates a new driver for the given parent key.
 *
 * @param parent This key specifies the parent of the key set the parser
 *               creates.
 */
Driver::Driver (Key const & parent)
{
	parents.push (parent.dup ());
}
예제 #8
0
	KeySet ks3 (5, *Key ("user/key3/1", KEY_END), *Key ("user/key3/2", KEY_END), *Key ("user/key3/3", KEY_VALUE, "value", KEY_END),
		    KS_END);
	// ks3.toStream(stdout, 0);

	Key k1 ("user/key4/1", KEY_END);
	Key k2 ("user/key4/2", KEY_END);
	Key k3 ("user/key4/3", KEY_VALUE, "value", KEY_END);
	KeySet ks4 (5,
		    *k1, // k1 will lose its key and pass it to keyset
		    *k2, *k3, KS_END);
	// ks4.toStream(stdout, 0);

	Key k4 ("user/key5/1", KEY_END);
	Key k5 ("user/key5/2", KEY_END);
	Key k6 ("user/key5/3", KEY_VALUE, "value", KEY_END);
	KeySet ks5 (5, k4.dup (), k5.dup (), k6.dup (), KS_END);
	// ks5.toStream(stdout, 0);
	// k4, k5, k6 can still be used

	KeySet ks6 = fun (5, k4.dup (), k5.dup (), k6.dup (), KS_END);
}


TEST (ks, dup)
{
	KeySet ks3 (5, *Key ("user/key3/1", KEY_END), *Key ("user/key3/2", KEY_END), *Key ("user/key3/3", KEY_VALUE, "value", KEY_END),
		    KS_END);
	succeed_if (ks3.lookup ("user/key3/1"), "could not find key");
	succeed_if (ks3.lookup ("user/key3/2"), "could not find key");
	succeed_if (ks3.lookup ("user/key3/3"), "could not find key");
	succeed_if (ks3.lookup ("user/key3/3").getString () == "value", "value not correct");
예제 #9
0
/**
 * @brief This constructor creates a Listener using the given parent key.
 *
 * @param parent This argument specifies the parent key of the key set this
 *               listener produces.
 */
Listener::Listener (Key const & parent)
{
	parents.push (parent.dup ());
}