diff options
| -rw-r--r-- | project2/basics/options/preload.cpp | 4 | ||||
| -rw-r--r-- | project2/basics/unittests/testLibraries.cpp | 5 | ||||
| -rw-r--r-- | project2/basics/unittests/testViews.cpp | 5 | ||||
| -rw-r--r-- | project2/cgi/cgiAppEngine.h | 3 | ||||
| -rw-r--r-- | project2/common/appInstance.cpp | 52 | ||||
| -rw-r--r-- | project2/common/appInstance.h | 26 | ||||
| -rw-r--r-- | project2/common/scriptLoader.cpp | 37 | ||||
| -rw-r--r-- | project2/common/scriptLoader.h | 6 | ||||
| -rw-r--r-- | project2/common/scripts.cpp | 23 | ||||
| -rw-r--r-- | project2/common/scripts.h | 14 | ||||
| -rw-r--r-- | project2/common/sourceObject.cpp | 5 | ||||
| -rw-r--r-- | project2/console/consoleAppEngine.h | 3 | ||||
| -rw-r--r-- | project2/daemon/p2daemonAppEngine.h | 3 | ||||
| -rw-r--r-- | project2/ice/iceDaemon.cpp | 3 | ||||
| -rw-r--r-- | project2/ice/iceDataSource.cpp | 3 | ||||
| -rw-r--r-- | project2/ice/unittests/testClient.cpp | 6 | ||||
| -rw-r--r-- | project2/ice/unittests/testClientCompile.cpp | 5 | ||||
| -rw-r--r-- | project2/ice/unittests/testDaemon.cpp | 5 | ||||
| -rw-r--r-- | project2/ice/unittests/testDaemonCompile.cpp | 5 | ||||
| -rw-r--r-- | project2/sql/unittests/testCore.h | 3 | 
20 files changed, 147 insertions, 69 deletions
diff --git a/project2/basics/options/preload.cpp b/project2/basics/options/preload.cpp index f871e57..5cf42e8 100644 --- a/project2/basics/options/preload.cpp +++ b/project2/basics/options/preload.cpp @@ -1,7 +1,7 @@  #include <pch.hpp>  #include <options.h>  #include <library.h> -#include <scripts.h> +#include <appInstance.h>  #include <boost/filesystem/path.hpp>  #include <map>  #include <dlfcn.h> @@ -42,7 +42,7 @@ class Preload {  		static void UnloadLibraries()  		{ -			ScriptReader::clearCache(); +			AppInstance::current().clearScriptCache();  			libs.clear();  		} diff --git a/project2/basics/unittests/testLibraries.cpp b/project2/basics/unittests/testLibraries.cpp index c7aac5a..b77b671 100644 --- a/project2/basics/unittests/testLibraries.cpp +++ b/project2/basics/unittests/testLibraries.cpp @@ -4,9 +4,12 @@  #include <testOptionsSource.h>  #include <exceptions.h>  #include <library.h> +#include <appInstance.h>  const auto self = boost::filesystem::canonical("/proc/self/exe"); +BOOST_FIXTURE_TEST_SUITE( Core, AppInstance ); +  BOOST_AUTO_TEST_CASE( load_missing_library )  {  	BOOST_TEST_CHECKPOINT("Configure (load)"); @@ -32,3 +35,5 @@ BOOST_AUTO_TEST_CASE( load_and_unload_library )  	BOOST_REQUIRE_THROW(ElementLoader::getFor("DummyTask"), NotSupported);  } +BOOST_AUTO_TEST_SUITE_END(); + diff --git a/project2/basics/unittests/testViews.cpp b/project2/basics/unittests/testViews.cpp index 8230ab9..a74c9e3 100644 --- a/project2/basics/unittests/testViews.cpp +++ b/project2/basics/unittests/testViews.cpp @@ -5,6 +5,7 @@  #include <testOptionsSource.h>  #include <testScriptHost.h>  #include <definedDirs.h> +#include <appInstance.h>  boost::intrusive_ptr<TestScriptHost>  executeRowViewTest(const boost::filesystem::path & script, const boost::filesystem::path & expected) @@ -23,6 +24,8 @@ executeRowViewTest(const boost::filesystem::path & script, const boost::filesyst  	return sr;  } +BOOST_FIXTURE_TEST_SUITE( Core, AppInstance ); +  BOOST_AUTO_TEST_CASE( test_rowview_unsetcolumns )  {  	executeRowViewTest(RootDir / "test_rowview_unsetcolumns.xml", RootDir / "expected" / "test_rowview_unsetcolumns.log"); @@ -38,3 +41,5 @@ BOOST_AUTO_TEST_CASE( test_rowview_columns )  	executeRowViewTest(RootDir / "test_rowview_columns.xml", RootDir / "expected" / "test_rowview_columns.log");  } +BOOST_AUTO_TEST_SUITE_END(); + diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 1bc282f..83b34d5 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -16,6 +16,7 @@  #include "cgiHttpHeader.h"  #include "cgiRequestContext.h"  #include <cgicc/Cgicc.h> +#include <appInstance.h>  class Session;  namespace cgicc { @@ -23,7 +24,7 @@ namespace cgicc {  	class CgiEnvironment;  } -class CgiApplicationEngine { +class CgiApplicationEngine : AppInstance {  	public:  		typedef boost::shared_ptr<Project2HttpHeader> HttpHeaderPtr;  		typedef std::pair<Glib::ustring, Glib::RefPtr<Glib::Regex>> PlatformHostname; diff --git a/project2/common/appInstance.cpp b/project2/common/appInstance.cpp new file mode 100644 index 0000000..72d34a9 --- /dev/null +++ b/project2/common/appInstance.cpp @@ -0,0 +1,52 @@ +#include "appInstance.h" +#include <boost/tuple/tuple_comparison.hpp> + +AppInstance * AppInstance::_current = nullptr; + +AppInstance::AppInstance() +{ +	if (_current) { +		throw std::runtime_error("One AppInstance at a time please"); +	} +	_current = this; +} + +AppInstance::~AppInstance() +{ +	if (_current != this) { +		throw std::runtime_error("All kinds of bad, destroying a non-current AppInstance"); +	} +	_current = NULL; +} + +AppInstance & +AppInstance::current() +{ +	if (!_current) { +		throw std::runtime_error("No current AppInstance"); +	} +	return *_current; +} + +ScriptReaderPtr +AppInstance::cachedScript(const ScriptReader::ScriptKey & sk) const +{ +	auto cached = scriptCache.find(sk); +	if (cached != scriptCache.end()) { +		return cached->second; +	} +	return nullptr; +} + +void +AppInstance::cacheScript(const ScriptReader::ScriptKey & sk, ScriptReaderPtr s) +{ +	scriptCache[sk] = s; +} + +void +AppInstance::clearScriptCache() +{ +	scriptCache.clear(); +} + diff --git a/project2/common/appInstance.h b/project2/common/appInstance.h new file mode 100644 index 0000000..50ade4d --- /dev/null +++ b/project2/common/appInstance.h @@ -0,0 +1,26 @@ +#ifndef APPINSTANCE_H +#define APPINSTANCE_H + +#include <set> +#include "scripts.h" + +class AppInstance { +	public: +		typedef std::map<ScriptReader::ScriptKey, ScriptReaderPtr> ScriptCache; + +		AppInstance(); +		virtual ~AppInstance() = 0; + +		static AppInstance & current(); + +		ScriptReaderPtr cachedScript(const ScriptReader::ScriptKey &) const; +		void cacheScript(const ScriptReader::ScriptKey &, ScriptReaderPtr); +		void clearScriptCache(); + +	private: +		static AppInstance * _current; +		ScriptCache scriptCache; +}; + +#endif + diff --git a/project2/common/scriptLoader.cpp b/project2/common/scriptLoader.cpp index 185f18d..56461d9 100644 --- a/project2/common/scriptLoader.cpp +++ b/project2/common/scriptLoader.cpp @@ -7,21 +7,7 @@  #include <boost/function.hpp>  #include <boost/function_equal.hpp>  #include "instanceStore.impl.h" - -unsigned int LoaderBase::depth = 0; -std::set<SourceObject *> LoaderBase::loadedObjects; - -class DepthCounter { -	public: -		DepthCounter(unsigned int & c) : counter(c) { -			counter += 1; -		} -		~DepthCounter() { -			counter -= 1; -		} -	private: -		unsigned int & counter; -}; +#include "appInstance.h"  typedef std::map<std::string, boost::shared_ptr<ElementLoader> > ElementLoaderMap;  typedef std::set<boost::shared_ptr<ComponentLoader> > ComponentLoaderSet; @@ -71,9 +57,8 @@ LoaderBase::getSub(ScriptNodePtr root, const Glib::ustring & name, bool required  }  void -LoaderBase::collectAll(ScriptNodePtr node, bool childrenOnly, const StorerPtrs & sts) const +LoaderBase::collectAll(ScriptNodePtr node, LoadedObjects & loadedObjects, bool childrenOnly, const StorerPtrs & sts) const  { -	DepthCounter dc(depth);  	unsigned int created = 0;  	if (!childrenOnly && node->componentNamespace()) {  		unsigned int stored = 0; @@ -91,10 +76,8 @@ LoaderBase::collectAll(ScriptNodePtr node, bool childrenOnly, const StorerPtrs &  				throw NotSupported(node->get_name());  			}  		} -		else { -			if (SourceObjectPtr p = boost::dynamic_pointer_cast<SourceObject>(node->obj)) { -				LoaderBase::loadedObjects.insert(p.get()); -			} +		if (SourceObjectPtr p = boost::dynamic_pointer_cast<SourceObject>(node->obj)) { +			loadedObjects.insert(p.get());  		}  		for (const StorerPtr & s : sts) {  			if (s->save(node->obj, node)) { @@ -111,7 +94,7 @@ LoaderBase::collectAll(ScriptNodePtr node, bool childrenOnly, const StorerPtrs &  	}  	if (created == 0 && (recursive || childrenOnly)) {  		for (ScriptNodePtr child : node->children()) { -			collectAll(child, false, sts); +			collectAll(child, loadedObjects, false, sts);  		}  	}  } @@ -120,20 +103,16 @@ void  LoaderBase::collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr node)  {  	addLoadTarget(node, Storer::into<ElementLoader>(&libraries)); -	if (depth != 0 && co) { -		throw std::logic_error("Cannot set CommonObjects in subloader"); -	}  	Targets::iterator i; -	ScopeObject clr(NULL, NULL, [] { loadedObjects.clear(); }); +	LoadedObjects loadedObjects;  	while ((i = targets.begin()) != targets.end()) { -		collectAll(i->first, childrenOnly, i->second); +		collectAll(i->first, loadedObjects, childrenOnly, i->second);  		targets.erase(i);  	}  	if (co) { -		for (SourceObjectPtr o : loadedObjects) { +		for (auto o : loadedObjects) {  			o->loadComplete(co);  		} -		loadedObjects.clear();  	}  } diff --git a/project2/common/scriptLoader.h b/project2/common/scriptLoader.h index 00ad9b5..ca888cf 100644 --- a/project2/common/scriptLoader.h +++ b/project2/common/scriptLoader.h @@ -24,6 +24,7 @@ class LoaderBase {  		typedef boost::intrusive_ptr<Storer> StorerPtr;  		typedef std::vector<StorerPtr> StorerPtrs;  		typedef std::map<ScriptNodePtr, StorerPtrs> Targets; +		typedef std::set<SourceObject *> LoadedObjects;  		LoaderBase();  		virtual ~LoaderBase(); @@ -34,12 +35,9 @@ class LoaderBase {  		void discardLoadTargets();  	private: -		void collectAll(ScriptNodePtr script, bool childrenOnly, const StorerPtrs & sts) const; +		void collectAll(ScriptNodePtr script, LoadedObjects &, bool childrenOnly, const StorerPtrs & sts) const;  		static ScriptNodePtr getSub(ScriptNodePtr root, const Glib::ustring & name, bool required);  		Targets targets; -		static unsigned int depth; -		friend class SourceObject; -		static std::set<SourceObject *> loadedObjects;  		const bool recursive; diff --git a/project2/common/scripts.cpp b/project2/common/scripts.cpp index 4f80b1a..ff80870 100644 --- a/project2/common/scripts.cpp +++ b/project2/common/scripts.cpp @@ -2,9 +2,7 @@  #include <algorithm>  #include "variables/fixed.h"  #include <boost/filesystem/convenience.hpp> -#include <boost/tuple/tuple_comparison.hpp> - -ScriptReader::ScriptCache ScriptReader::scriptCache; +#include "appInstance.h"  DECLARE_OPTIONS(Scripts, "Project2 Script options")  ("common.namespace", Options::value(&scriptNamespace, "http://project2.randomdan.homeip.net"), @@ -17,7 +15,7 @@ std::string Scripts::scriptNamespacePrefix;  std::string Scripts::scriptNamespace;  ScriptNode::ScriptNode(ScriptReaderPtr s) : -	script(s) +	script(s.get())  {  } @@ -66,27 +64,22 @@ ScriptReader::load(const CommonObjects * co, bool childrenOnly) const  	loader.collectAll(co, childrenOnly, root());  } -void -ScriptReader::clearCache() -{ -	scriptCache.clear(); -} -  ScriptReaderPtr  ScriptReader::resolveScript(const std::string & group, const std::string & name, bool ii)  {  	boost::filesystem::path e(name);  	while (!e.empty()) {  		ScriptKey sk(group, e.string()); -		ScriptCache::const_iterator i = scriptCache.find(sk); -		if (i != scriptCache.end() && i->second->isCurrent()) { -			return i->second; +		ScriptReaderPtr rs = AppInstance::current().cachedScript(sk); +		if (rs) { +			return rs;  		}  		else {  			for (const auto & rl : InstanceSet<ScriptReaderLoader>::GetAll()) { -				ScriptReaderPtr rs = rl->resolveScript(group, e.string()); +				rs = rl->resolveScript(group, e.string());  				if (rs) { -					return (scriptCache[sk] = rs); +					AppInstance::current().cacheScript(sk, rs); +					return rs;  				}  			}  		} diff --git a/project2/common/scripts.h b/project2/common/scripts.h index 775a080..8bf450d 100644 --- a/project2/common/scripts.h +++ b/project2/common/scripts.h @@ -38,7 +38,7 @@ class ScriptNode : public IntrusivePtrBase {  		virtual bool componentNamespace() const = 0;  		virtual std::string get_name() const = 0; -		 +  		// Child called name  		virtual ScriptNodePtr child(const Glib::ustring & name, bool required = true) const = 0;  		// All children @@ -46,7 +46,7 @@ class ScriptNode : public IntrusivePtrBase {  		virtual ScriptNodes children(const Glib::ustring & name) const;  		// All children in sub  		virtual ScriptNodes childrenIn(const Glib::ustring & sub) const = 0; -		 +  		virtual bool valueExists(const Glib::ustring & name) const = 0;  		virtual bool applyValue(const Glib::ustring & name, VariableType & target, ExecContext *) const = 0;  		virtual VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource = boost::optional<Glib::ustring>()) const = 0; @@ -56,7 +56,7 @@ class ScriptNode : public IntrusivePtrBase {  		VariableType value(const Glib::ustring & name, const VariableType & def, ExecContext *) const;  		virtual void composeWithCallbacks(const LiteralCallback &, const NodeCallback &) const = 0; -		const ScriptReaderPtr script; +		const ScriptReader * script;  	private:  		friend class LoaderBase;  		mutable boost::intrusive_ptr<IntrusivePtrBase> obj; @@ -64,6 +64,8 @@ class ScriptNode : public IntrusivePtrBase {  class ScriptReader : public virtual IntrusivePtrBase {  	public: +		typedef boost::tuple<const std::string, const std::string> ScriptKey; +  		virtual ~ScriptReader() { }  		virtual ScriptNodePtr root() const = 0; @@ -73,15 +75,9 @@ class ScriptReader : public virtual IntrusivePtrBase {  		mutable LoaderBase loader;  		static ScriptReaderPtr resolveScript(const std::string & group, const std::string & name, bool ii); -		static void clearCache();  		friend class SourceObject;  		mutable std::map<std::string, SourceObject *> namedComponents; - -	private: -		typedef boost::tuple<const std::string, const std::string> ScriptKey; -		typedef std::map<ScriptKey, ScriptReaderPtr> ScriptCache; -		static ScriptCache scriptCache;  };  /// Base class to implement script reader modules diff --git a/project2/common/sourceObject.cpp b/project2/common/sourceObject.cpp index a76bdec..aa81d01 100644 --- a/project2/common/sourceObject.cpp +++ b/project2/common/sourceObject.cpp @@ -11,9 +11,8 @@ SimpleMessageException(ComponentNotFound);  SourceObject::SourceObject(ScriptNodePtr p) :  	name(p ? p->value("name", "anon", NULL).as<std::string>() : "anon"),  	order(loadOrder++), -	script(p->script.get()) +	script(p->script)  { -	LoaderBase::loadedObjects.insert(this);  	script->namedComponents[name] = this;  } @@ -22,12 +21,10 @@ SourceObject::SourceObject(const std::string & n) :  	order(loadOrder++),  	script(NULL)  { -	LoaderBase::loadedObjects.insert(this);  }  SourceObject::~SourceObject()  { -	LoaderBase::loadedObjects.erase(this);  }  void diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h index f4017e4..d545e27 100644 --- a/project2/console/consoleAppEngine.h +++ b/project2/console/consoleAppEngine.h @@ -8,8 +8,9 @@  #include "execContext.h"  #include <vector>  #include <boost/tuple/tuple.hpp> +#include <appInstance.h> -class ConsoleApplicationEngine : public ExecContext { +class ConsoleApplicationEngine : public ExecContext, AppInstance {  	public:  		ConsoleApplicationEngine();  		virtual ~ConsoleApplicationEngine(); diff --git a/project2/daemon/p2daemonAppEngine.h b/project2/daemon/p2daemonAppEngine.h index 84601bd..19bd000 100644 --- a/project2/daemon/p2daemonAppEngine.h +++ b/project2/daemon/p2daemonAppEngine.h @@ -7,8 +7,9 @@  #include "lib/daemon.h"  #include <thread>  #include <glibmm/main.h> +#include <appInstance.h> -class DaemonAppEngine { +class DaemonAppEngine : AppInstance {  	public:  		DaemonAppEngine(int, char **);  		~DaemonAppEngine(); diff --git a/project2/ice/iceDaemon.cpp b/project2/ice/iceDaemon.cpp index cd752b8..860cd86 100644 --- a/project2/ice/iceDaemon.cpp +++ b/project2/ice/iceDaemon.cpp @@ -17,6 +17,7 @@  #include <execContext.h>  #include <misc.h>  #include <exceptions.h> +#include "appInstance.h"  std::string IceDaemon::adapterName;  std::string IceDaemon::adapterEndpoint; @@ -177,7 +178,7 @@ IceDaemon::GetComponentCompiler(const std::string & slice, const IceCompile::Dep  void  IceDaemon::ClearSlice()  { -	ScriptReader::clearCache(); +	AppInstance::current().clearScriptCache();  	libs.clear();  } diff --git a/project2/ice/iceDataSource.cpp b/project2/ice/iceDataSource.cpp index 0493a58..7871500 100644 --- a/project2/ice/iceDataSource.cpp +++ b/project2/ice/iceDataSource.cpp @@ -4,6 +4,7 @@  #include <scripts.h>  #include <logger.h>  #include <Ice/Ice.h> +#include "appInstance.h"  IceBase::Libs IceDataSource::libs;  IceDataSource::Proxies IceDataSource::proxies; @@ -35,7 +36,7 @@ IceDataSource::GetComponentCompiler(const std::string & slice, const IceCompile:  void  IceDataSource::ClearSlice()  { -	ScriptReader::clearCache(); +	AppInstance::current().clearScriptCache();  	libs.clear();  	proxies.clear();  } diff --git a/project2/ice/unittests/testClient.cpp b/project2/ice/unittests/testClient.cpp index 3b3c790..97acd0b 100644 --- a/project2/ice/unittests/testClient.cpp +++ b/project2/ice/unittests/testClient.cpp @@ -13,6 +13,7 @@  #include <scopeObject.h>  #include <unittest.h>  #include <unittestComplex.h> +#include <appInstance.h>  #define XSTR(s) STR(s)  #define STR(s) #s @@ -152,6 +153,9 @@ unloadTests()  }  void test_client_run(const boost::filesystem::path & tmpdir); + +BOOST_FIXTURE_TEST_SUITE( Core, AppInstance ); +  BOOST_AUTO_TEST_CASE( test_client )  {  	const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-client"; @@ -163,6 +167,8 @@ BOOST_AUTO_TEST_CASE( test_client )  	boost::filesystem::remove_all(tmpdir);  } +BOOST_AUTO_TEST_SUITE_END(); +  void test_client_run(const boost::filesystem::path & tmpdir)  {  	BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); diff --git a/project2/ice/unittests/testClientCompile.cpp b/project2/ice/unittests/testClientCompile.cpp index 944af60..3b27d63 100644 --- a/project2/ice/unittests/testClientCompile.cpp +++ b/project2/ice/unittests/testClientCompile.cpp @@ -8,6 +8,7 @@  #include <scripts.h>  #include <testScriptHost.h>  #include <scopeObject.h> +#include <appInstance.h>  #define XSTR(s) STR(s)  #define STR(s) #s @@ -40,6 +41,8 @@ unloadTests()  	BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams"), NotSupported);  } +BOOST_FIXTURE_TEST_SUITE( Core, AppInstance ); +  BOOST_AUTO_TEST_CASE( compile_client_full )  {  	TestOptionsSource::LoadTestOptions({ }); @@ -120,3 +123,5 @@ BOOST_AUTO_TEST_CASE( compile_client_slicer )  	boost::filesystem::remove_all(tmpdir);  } +BOOST_AUTO_TEST_SUITE_END(); + diff --git a/project2/ice/unittests/testDaemon.cpp b/project2/ice/unittests/testDaemon.cpp index 4e48413..a01782e 100644 --- a/project2/ice/unittests/testDaemon.cpp +++ b/project2/ice/unittests/testDaemon.cpp @@ -8,6 +8,7 @@  #include <task.h>  #include <logger.h>  #include <variables.h> +#include <appInstance.h>  #define XSTR(s) STR(s)  #define STR(s) #s @@ -195,6 +196,8 @@ unloadTests()  	BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerLoader::createNew("UnitTest-SimpleInterface", NULL), NotSupported);  } +BOOST_FIXTURE_TEST_SUITE( Core, AppInstance ); +  BOOST_AUTO_TEST_CASE( test_daemon )  {  	const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemon"; @@ -227,3 +230,5 @@ BOOST_AUTO_TEST_CASE( test_daemon )  	boost::filesystem::remove_all(tmpdir);  } +BOOST_AUTO_TEST_SUITE_END(); + diff --git a/project2/ice/unittests/testDaemonCompile.cpp b/project2/ice/unittests/testDaemonCompile.cpp index a49719f..02c64d6 100644 --- a/project2/ice/unittests/testDaemonCompile.cpp +++ b/project2/ice/unittests/testDaemonCompile.cpp @@ -4,6 +4,7 @@  #include <testOptionsSource.h>  #include <exceptions.h>  #include <iceDaemon.h> +#include <appInstance.h>  #define XSTR(s) STR(s)  #define STR(s) #s @@ -28,6 +29,8 @@ unloadTests()  	BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerLoader::createNew("UnitTest-SimpleInterface", NULL), NotSupported);  } +BOOST_FIXTURE_TEST_SUITE( Core, AppInstance ); +  BOOST_AUTO_TEST_CASE( compile_daemon_full )  {  	const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemonCompile/full"; @@ -102,3 +105,5 @@ BOOST_AUTO_TEST_CASE( compile_daemon_slicer )  	boost::filesystem::remove_all(tmpdir);  } +BOOST_AUTO_TEST_SUITE_END(); + diff --git a/project2/sql/unittests/testCore.h b/project2/sql/unittests/testCore.h index 2b5be0e..0a667d6 100644 --- a/project2/sql/unittests/testCore.h +++ b/project2/sql/unittests/testCore.h @@ -3,8 +3,9 @@  #include <commonObjects.h>  #include <variableType.h> +#include <appInstance.h> -class TestCore : public CommonObjects { +class TestCore : public CommonObjects, AppInstance {  	public:  		TestCore();  | 
