summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/BuildAndReleaseOptions.html33
-rw-r--r--mak/config.mak20
-rw-r--r--src/Pegasus/Common/CIMObjectPath.h2
-rw-r--r--src/Pegasus/Repository/CIMRepository.cpp6
-rw-r--r--src/Pegasus/Repository/FileBasedStore.cpp13
-rw-r--r--src/Pegasus/Repository/FileBasedStore.h14
-rw-r--r--src/Pegasus/Repository/Makefile21
-rw-r--r--src/Pegasus/Repository/NameSpaceManager.h4
-rw-r--r--src/Pegasus/Repository/PersistentStore.cpp69
-rw-r--r--src/Pegasus/Repository/PersistentStore.h195
-rw-r--r--src/Pegasus/Repository/SQLiteStore.cpp2106
-rw-r--r--src/Pegasus/Repository/SQLiteStore.h231
-rw-r--r--src/Pegasus/msg/Server/pegasusServer_en.txt27
13 files changed, 2723 insertions, 18 deletions
diff --git a/doc/BuildAndReleaseOptions.html b/doc/BuildAndReleaseOptions.html
index 77fca01..65fd5f6 100644
--- a/doc/BuildAndReleaseOptions.html
+++ b/doc/BuildAndReleaseOptions.html
@@ -1658,6 +1658,22 @@ additional information.</p>
titled "Configuration Properties" for additional detail.<br>
</ul>
+<h5>PEGASUS_USE_SQLITE_REPOSITORY</h5>
+<ul>
+ <b>Description:&nbsp;</b>If true, new repository stores are created
+ using a SQLite database. Existing file-based stores will continue
+ to be recognized and operate seamlessly.<br>
+ <b>Default Value:&nbsp;</b>false<br>
+ <b>Recommended Value (Development Build):&nbsp;</b>true<br>
+ <b>Recommended Value (Release Build):&nbsp;</b>true<br>
+ <b>Required:&nbsp;</b>No<br>
+ <b>Considerations:&nbsp;</b>If PEGASUS_USE_SQLITE_REPOSITORY is set to true
+ and SQLite files are not installed in default search locations,
+ SQLITE_HOME must also be configured.
+ PEGASUS_REPOSITORY_STORE_COMPLETE_CLASSES may not be set to true when
+ PEGASUS_USE_SQLITE_REPOSITORY is set to true.
+</ul>
+
<h5>PEGASUS_USE_SYSLOGS</h5>
<ul>
<b>Description:&nbsp;</b>If set, OpenPegasus will be built
@@ -1688,6 +1704,23 @@ additional information.</p>
compiler version &lt; 1300.<br>
</ul>
+<h5>SQLITE_HOME</h5>
+<ul>
+ <b>Description:&nbsp;</b>Specifies the location of the SQLite SDK directory.
+ This directory must contain sqlite3.h in the $(SQLITE_HOME)/include
+ directory, and libsqlite3 in the $(SQLITE_HOME)/lib directory.<br>
+ <b>Default Value:&nbsp;</b>Not Set<br>
+ <b>Recommended Value (Development Build):&nbsp;</b>
+ No Specific Recommendation<br>
+ <b>Recommended Value (Release Build):&nbsp;</b>
+ No Specific Recommendation<br>
+ <b>Required:&nbsp;</b>Yes, if PEGASUS_USE_SQLITE_REPOSITORY is set to true
+ and the SQLite files are not installed in locations that are searched by
+ default.<br>
+ <b>Considerations:&nbsp;</b>This environment variable is only used if
+ PEGASUS_USE_SQLITE_REPOSITORY is set to true.
+</ul>
+
<h4>Examples Building a Linux IA32 (#IA64) Development/Debug Version</h4>
<ul>
export PEGASUS_ROOT=/home/pegasusbld/pegasus<br>
diff --git a/mak/config.mak b/mak/config.mak
index ed59c75..632045f 100644
--- a/mak/config.mak
+++ b/mak/config.mak
@@ -554,8 +554,26 @@ else
endif
endif
+# SQLite repository support
+
+ifndef PEGASUS_USE_SQLITE_REPOSITORY
+ PEGASUS_USE_SQLITE_REPOSITORY = false
+endif
+
+ifeq ($(PEGASUS_USE_SQLITE_REPOSITORY),true)
+ ifeq ($(PEGASUS_REPOSITORY_STORE_COMPLETE_CLASSES),true)
+ $(error PEGASUS_REPOSITORY_STORE_COMPLETE_CLASSES may not be set to true when PEGASUS_USE_SQLITE_REPOSITORY is true)
+ endif
+ DEFINES += -DPEGASUS_USE_SQLITE_REPOSITORY
+else
+ ifneq ($(PEGASUS_USE_SQLITE_REPOSITORY),false)
+ $(error PEGASUS_USE_SQLITE_REPOSITORY ($(PEGASUS_USE_SQLITE_REPOSITORY)) invalid, must be true or false)
+ endif
+endif
+
# PEP 161
-# Control whether utf-8 filenames are supported by the repository
+# Control whether utf-8 filenames are supported by the repository.
+# Note: These options only apply to the file-based repository, not SQLite.
ifdef PEGASUS_SUPPORT_UTF8_FILENAME
DEFINES += -DPEGASUS_SUPPORT_UTF8_FILENAME
diff --git a/src/Pegasus/Common/CIMObjectPath.h b/src/Pegasus/Common/CIMObjectPath.h
index 27596cd..7c05866 100644
--- a/src/Pegasus/Common/CIMObjectPath.h
+++ b/src/Pegasus/Common/CIMObjectPath.h
@@ -594,6 +594,8 @@ private:
String _toStringCanonical() const;
CIMObjectPathRep* _rep;
+
+ friend class SQLiteStore;
};
/**
diff --git a/src/Pegasus/Repository/CIMRepository.cpp b/src/Pegasus/Repository/CIMRepository.cpp
index 0e084b4..58c42a5 100644
--- a/src/Pegasus/Repository/CIMRepository.cpp
+++ b/src/Pegasus/Repository/CIMRepository.cpp
@@ -53,7 +53,7 @@
#include "RepositoryDeclContext.h"
#include "ObjectCache.h"
-#include "FileBasedStore.h"
+#include "PersistentStore.h"
#if 0
#undef PEG_METHOD_ENTER
@@ -91,7 +91,7 @@ public:
AutoPtr<ObjectStreamer> _streamer;
- AutoPtr<FileBasedStore> _persistentStore;
+ AutoPtr<PersistentStore> _persistentStore;
/**
Indicates whether the class definitions in the persistent store are
@@ -706,7 +706,7 @@ CIMRepository::CIMRepository(
_rep->_lockFile = ConfigManager::getInstance()->getHomedPath(
PEGASUS_REPOSITORY_LOCK_FILE).getCString();
- _rep->_persistentStore.reset(new FileBasedStore(
+ _rep->_persistentStore.reset(PersistentStore::createPersistentStore(
repositoryRoot,
_rep->_streamer.get(),
compressMode));
diff --git a/src/Pegasus/Repository/FileBasedStore.cpp b/src/Pegasus/Repository/FileBasedStore.cpp
index e74268f..7334d86 100644
--- a/src/Pegasus/Repository/FileBasedStore.cpp
+++ b/src/Pegasus/Repository/FileBasedStore.cpp
@@ -501,6 +501,13 @@ private:
//
////////////////////////////////////////////////////////////////////////////////
+Boolean FileBasedStore::isExistingRepository(const String& repositoryRoot)
+{
+ // If this is an existing FileBasedStore repository directory, a "root"
+ // subdirectory will exist.
+ return FileSystem::isDirectory(repositoryRoot + "/root");
+}
+
FileBasedStore::FileBasedStore(
const String& repositoryPath,
ObjectStreamer* streamer,
@@ -533,10 +540,10 @@ FileBasedStore::FileBasedStore(
String configFilePath = _repositoryPath + "/" + _CONFIGFILE_NAME;
- if (!FileSystem::isDirectory(_repositoryPath + "/root"))
+ if (!FileBasedStore::isExistingRepository(_repositoryPath))
{
- // The root namespace does not exist so this must be a new repository
- // instance. Use the setting defined by the build option.
+ // This is a new repository instance. Use the setting defined by
+ // the build option.
#ifndef PEGASUS_REPOSITORY_STORE_COMPLETE_CLASSES
PEGASUS_STD(ofstream) os;
diff --git a/src/Pegasus/Repository/FileBasedStore.h b/src/Pegasus/Repository/FileBasedStore.h
index e72f97a..3b4fda2 100644
--- a/src/Pegasus/Repository/FileBasedStore.h
+++ b/src/Pegasus/Repository/FileBasedStore.h
@@ -35,22 +35,20 @@
#define Pegasus_FileBasedStore_h
#include <Pegasus/Common/Config.h>
-#include <Pegasus/Common/String.h>
-#include <Pegasus/Common/CIMClass.h>
-#include <Pegasus/Common/CIMQualifierDecl.h>
-#include <Pegasus/Common/CIMObjectPath.h>
-#include <Pegasus/Common/CIMInstance.h>
-#include <Pegasus/Common/AutoStreamer.h>
-#include <Pegasus/Common/Pair.h>
#include <Pegasus/Common/HashTable.h>
+#include <Pegasus/Repository/PersistentStore.h>
#include <Pegasus/Repository/PersistentStoreData.h>
#include <Pegasus/Repository/AssocClassTable.h>
+#include <Pegasus/Repository/Linkage.h>
PEGASUS_NAMESPACE_BEGIN
-class PEGASUS_REPOSITORY_LINKAGE FileBasedStore
+class PEGASUS_REPOSITORY_LINKAGE FileBasedStore : public PersistentStore
{
public:
+
+ static Boolean isExistingRepository(const String& repositoryRoot);
+
FileBasedStore(
const String& repositoryPath,
ObjectStreamer* streamer,
diff --git a/src/Pegasus/Repository/Makefile b/src/Pegasus/Repository/Makefile
index 5455715..bf9e1a9 100644
--- a/src/Pegasus/Repository/Makefile
+++ b/src/Pegasus/Repository/Makefile
@@ -34,6 +34,12 @@ DIR = Pegasus/Repository
include $(ROOT)/mak/config.mak
+ifeq ($(PEGASUS_USE_SQLITE_REPOSITORY),true)
+ ifdef SQLITE_HOME
+ SYS_INCLUDES += -I$(SQLITE_HOME)/include
+ endif
+endif
+
EXTRA_INCLUDES = -I..
LOCAL_DEFINES = -DPEGASUS_REPOSITORY_INTERNAL -DPEGASUS_INTERNALONLY
@@ -44,6 +50,17 @@ ifeq ($(PEGASUS_PLATFORM),SOLARIS_SPARC_CC)
EXTRA_LIBRARIES += -lCstd
endif
+ifeq ($(PEGASUS_USE_SQLITE_REPOSITORY),true)
+ ifeq ($(OS_TYPE),windows)
+ SYS_LIBS += /libpath:$(SQLITE_HOME)/lib libsqlite3.lib
+ else
+ ifdef SQLITE_HOME
+ EXTRA_LIBRARIES += -L$(SQLITE_HOME)/lib
+ endif
+ EXTRA_LIBRARIES += -lsqlite3
+ endif
+endif
+
##
## PEP214 Compressed repository
## ----------------------------
@@ -111,8 +128,12 @@ else
SOURCES += AssocInstTable.cpp
SOURCES += InstanceIndexFile.cpp
SOURCES += InstanceDataFile.cpp
+ SOURCES += PersistentStore.cpp
SOURCES += FileBasedStore.cpp
SOURCES += CIMRepository.cpp
+ ifeq ($(PEGASUS_USE_SQLITE_REPOSITORY),true)
+ SOURCES += SQLiteStore.cpp
+ endif
endif
include $(ROOT)/mak/library.mak
diff --git a/src/Pegasus/Repository/NameSpaceManager.h b/src/Pegasus/Repository/NameSpaceManager.h
index 44fdf62..0a743e2 100644
--- a/src/Pegasus/Repository/NameSpaceManager.h
+++ b/src/Pegasus/Repository/NameSpaceManager.h
@@ -35,11 +35,11 @@
#define Pegasus_NameSpaceManager_h
#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/Pair.h>
#include <Pegasus/Repository/InheritanceTree.h>
+#include <Pegasus/Repository/PersistentStoreData.h>
#include <Pegasus/Repository/Linkage.h>
-#include <Pegasus/Repository/FileBasedStore.h>
-
PEGASUS_NAMESPACE_BEGIN
struct NameSpaceManagerRep;
diff --git a/src/Pegasus/Repository/PersistentStore.cpp b/src/Pegasus/Repository/PersistentStore.cpp
new file mode 100644
index 0000000..57af90a
--- /dev/null
+++ b/src/Pegasus/Repository/PersistentStore.cpp
@@ -0,0 +1,69 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <Pegasus/Common/Config.h>
+#include <cctype>
+#include <cstdio>
+#include <fstream>
+
+#include "PersistentStore.h"
+#include "FileBasedStore.h"
+#ifdef PEGASUS_USE_SQLITE_REPOSITORY
+# include "SQLiteStore.h"
+#endif
+
+PEGASUS_NAMESPACE_BEGIN
+
+PersistentStore* PersistentStore::createPersistentStore(
+ const String& repositoryPath,
+ ObjectStreamer* streamer,
+ Boolean compressMode)
+{
+#ifdef PEGASUS_USE_SQLITE_REPOSITORY
+ if (SQLiteStore::isExistingRepository(repositoryPath))
+ {
+ return new SQLiteStore(repositoryPath, streamer);
+ }
+
+ if (FileBasedStore::isExistingRepository(repositoryPath))
+ {
+ return new FileBasedStore(repositoryPath, streamer, compressMode);
+ }
+
+ return new SQLiteStore(repositoryPath, streamer);
+#else
+ return new FileBasedStore(repositoryPath, streamer, compressMode);
+#endif
+}
+
+PEGASUS_NAMESPACE_END
diff --git a/src/Pegasus/Repository/PersistentStore.h b/src/Pegasus/Repository/PersistentStore.h
new file mode 100644
index 0000000..86b92b6
--- /dev/null
+++ b/src/Pegasus/Repository/PersistentStore.h
@@ -0,0 +1,195 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#ifndef Pegasus_PersistentStore_h
+#define Pegasus_PersistentStore_h
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/String.h>
+#include <Pegasus/Common/CIMClass.h>
+#include <Pegasus/Common/CIMQualifierDecl.h>
+#include <Pegasus/Common/CIMObjectPath.h>
+#include <Pegasus/Common/CIMInstance.h>
+#include <Pegasus/Common/AutoStreamer.h>
+#include <Pegasus/Common/Pair.h>
+#include <Pegasus/Repository/PersistentStoreData.h>
+
+PEGASUS_NAMESPACE_BEGIN
+
+class PersistentStore
+{
+public:
+ static PersistentStore* createPersistentStore(
+ const String& repositoryPath,
+ ObjectStreamer* streamer,
+ Boolean compressMode);
+
+ virtual ~PersistentStore() { }
+
+ virtual Boolean storeCompleteClassDefinitions() = 0;
+
+ virtual Array<NamespaceDefinition> enumerateNameSpaces() = 0;
+ virtual void createNameSpace(
+ const CIMNamespaceName& nameSpace,
+ Boolean shareable,
+ Boolean updatesAllowed,
+ const String& parent) = 0;
+ virtual void modifyNameSpace(
+ const CIMNamespaceName& nameSpace,
+ Boolean shareable,
+ Boolean updatesAllowed) = 0;
+ virtual void deleteNameSpace(const CIMNamespaceName& nameSpace) = 0;
+ virtual Boolean isNameSpaceEmpty(const CIMNamespaceName& nameSpace) = 0;
+
+ virtual Array<CIMQualifierDecl> enumerateQualifiers(
+ const CIMNamespaceName& nameSpace) = 0;
+ /**
+ Gets a qualifier declaration for a specified qualifier name in a
+ specified namespace. Returns an uninitialized object if the qualifier
+ is not found.
+ */
+ virtual CIMQualifierDecl getQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& qualifierName) = 0;
+ virtual void setQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMQualifierDecl& qualifierDecl) = 0;
+ virtual void deleteQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& qualifierName) = 0;
+
+ virtual Array<Pair<String, String> > enumerateClassNames(
+ const CIMNamespaceName& nameSpace) = 0;
+ virtual CIMClass getClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className,
+ const CIMName& superClassName) = 0;
+ /**
+ Creates a class definition. If the class is an association class,
+ the class association entries are also added.
+ */
+ virtual void createClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMClass& newClass,
+ const Array<ClassAssociation>& classAssocEntries) = 0;
+ /**
+ Modifies a class definition. If the class is an association class,
+ the class association entries are also updated to the specified set.
+ */
+ virtual void modifyClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMClass& modifiedClass,
+ const CIMName& oldSuperClassName,
+ Boolean isAssociation,
+ const Array<ClassAssociation>& classAssocEntries) = 0;
+ /**
+ Deletes a class definition. If the class is an association class,
+ the class association entries are also deleted. It is expected to
+ have already been verified that no instances of this class exist. A
+ list of dependent namespace names is provided to allow appropriate
+ clean-up of instance files, if necessary.
+ */
+ virtual void deleteClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className,
+ const CIMName& superClassName,
+ Boolean isAssociation,
+ const Array<CIMNamespaceName>& dependentNameSpaceNames) = 0;
+
+ virtual Array<CIMObjectPath> enumerateInstanceNamesForClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className) = 0;
+ virtual Array<CIMInstance> enumerateInstancesForClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className) = 0;
+ virtual CIMInstance getInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName) = 0;
+ /**
+ Creates an instance definition. If it is an association instance,
+ the instance association entries are also added.
+ */
+ virtual void createInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const CIMInstance& cimInstance,
+ const Array<InstanceAssociation>& instAssocEntries) = 0;
+ virtual void modifyInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const CIMInstance& cimInstance) = 0;
+ /**
+ Deletes an instance definition. If it is an association instance,
+ the instance association entries are also deleted.
+ */
+ virtual void deleteInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName) = 0;
+ virtual Boolean instanceExists(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName) = 0;
+
+ virtual void getClassAssociatorNames(
+ const CIMNamespaceName& nameSpace,
+ const Array<CIMName>& classList,
+ const Array<CIMName>& assocClassList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ const String& resultRole,
+ Array<String>& associatorNames) = 0;
+ virtual void getClassReferenceNames(
+ const CIMNamespaceName& nameSpace,
+ const Array<CIMName>& classList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ Array<String>& referenceNames) = 0;
+
+ virtual void getInstanceAssociatorNames(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const Array<CIMName>& assocClassList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ const String& resultRole,
+ Array<String>& associatorNames) = 0;
+ virtual void getInstanceReferenceNames(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ Array<String>& referenceNames) = 0;
+};
+
+PEGASUS_NAMESPACE_END
+
+#endif /* Pegasus_PersistentStore_h */
diff --git a/src/Pegasus/Repository/SQLiteStore.cpp b/src/Pegasus/Repository/SQLiteStore.cpp
new file mode 100644
index 0000000..0167cc3
--- /dev/null
+++ b/src/Pegasus/Repository/SQLiteStore.cpp
@@ -0,0 +1,2106 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#include <Pegasus/Common/Config.h>
+#include <cctype>
+#include <cstdio>
+
+#include <Pegasus/Common/InternalException.h>
+#include <Pegasus/Common/DeclContext.h>
+#include <Pegasus/Common/Resolver.h>
+#include <Pegasus/Common/System.h>
+#include <Pegasus/Common/Tracer.h>
+#include <Pegasus/Common/MessageLoader.h>
+#include <Pegasus/Common/FileSystem.h>
+#include <Pegasus/Common/CIMNameUnchecked.h>
+#include "SQLiteStore.h"
+
+PEGASUS_NAMESPACE_BEGIN
+
+struct CloseSQLiteDb
+{
+ void operator()(sqlite3* db)
+ {
+ // This operator may be invoked automatically when an exception is
+ // thrown, so it should not throw an exception itself.
+
+ int rc = sqlite3_close(db);
+
+ // It is expected that all prepared statements are finalized before
+ // this operator is invoked.
+ PEGASUS_ASSERT(rc == SQLITE_OK);
+ }
+};
+
+struct FinalizeSQLiteStatement
+{
+ void operator()(sqlite3_stmt* stmt)
+ {
+ if (stmt)
+ {
+ sqlite3_finalize(stmt);
+ }
+ }
+};
+
+// Size optimization: Keep the exception throwing logic in a function so it
+// does not get replicated with each error check.
+static void _throwSQLiteOperationException(sqlite3* db)
+{
+ throw Exception(MessageLoaderParms(
+ "Repository.SQLiteStore.DB_OP_ERROR",
+ "Repository SQLite database operation failed with error $0: $1",
+ sqlite3_errcode(db),
+ String((const Char16*)sqlite3_errmsg16(db))));
+}
+
+inline void CHECK_RC_OK(int rc, sqlite3* db)
+{
+ if (rc != SQLITE_OK)
+ {
+ _throwSQLiteOperationException(db);
+ }
+}
+
+inline void CHECK_RC_DONE(int rc, sqlite3* db)
+{
+ if (rc != SQLITE_DONE)
+ {
+ _throwSQLiteOperationException(db);
+ }
+}
+
+Boolean SQLiteStore::isExistingRepository(const String& repositoryRoot)
+{
+ return FileSystem::exists(repositoryRoot + "/root.db");
+}
+
+SQLiteStore::SQLiteStore(
+ const String& repositoryRoot,
+ ObjectStreamer* streamer)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::SQLiteStore");
+
+ // Create the repository directory if it does not already exist.
+
+ if (!FileSystem::isDirectory(repositoryRoot))
+ {
+ if (!FileSystem::makeDirectory(repositoryRoot))
+ {
+ PEG_METHOD_EXIT();
+ throw CannotCreateDirectory(repositoryRoot);
+ }
+ }
+
+ _repositoryRoot = repositoryRoot;
+ _streamer = streamer;
+
+ PEG_METHOD_EXIT();
+}
+
+SQLiteStore::~SQLiteStore()
+{
+}
+
+sqlite3* SQLiteStore::_openDb(const char* fileName)
+{
+ sqlite3* db;
+
+ int rc = sqlite3_open(fileName, &db);
+ if (rc != SQLITE_OK)
+ {
+ sqlite3_close(db);
+ throw Exception(MessageLoaderParms(
+ "Repository.SQLiteStore.DB_OPEN_ERROR",
+ "Failed to open SQLite repository database file \"$0\".",
+ fileName));
+ }
+
+ return db;
+}
+
+sqlite3* SQLiteStore::_openDb(const CIMNamespaceName& nameSpace)
+{
+ return _openDb(_getDbPath(nameSpace).getCString());
+}
+
+void SQLiteStore::_execDbStatement(
+ sqlite3* db,
+ const char* sqlStatement)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::_execDbStatement");
+
+ PEG_TRACE((TRC_REPOSITORY, Tracer::LEVEL4,
+ "Executing SQLite operation \"%s\"", sqlStatement));
+
+ char* zErrMsg = 0;
+ int rc = sqlite3_exec(db, sqlStatement, 0, 0, &zErrMsg);
+ if (rc)
+ {
+ PEG_TRACE((TRC_REPOSITORY, Tracer::LEVEL1,
+ "SQLite operation \"%s\" failed with error code %d: %s",
+ sqlStatement,
+ rc,
+ zErrMsg));
+ MessageLoaderParms parms(
+ "Repository.SQLiteStore.DB_OP_ERROR",
+ "Repository SQLite database operation failed with error $0: $1",
+ rc,
+ zErrMsg);
+ sqlite3_free(zErrMsg);
+ PEG_METHOD_EXIT();
+ throw Exception(parms);
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::_initSchema(sqlite3* db)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::_initSchema");
+
+ // The NamespaceTable contains a single row describing the namespace
+ // corresponding to the database file.
+ _execDbStatement(
+ db,
+ "CREATE TABLE NamespaceTable("
+ "nsname TEXT PRIMARY KEY NOT NULL,"
+ "shareable INTEGER NOT NULL,"
+ "updatesallowed INTEGER NOT NULL,"
+ "parentnsname TEXT NOT NULL,"
+ "remoteinfo TEXT NOT NULL);");
+
+ _execDbStatement(
+ db,
+ "CREATE TABLE QualifierTable("
+ "qualname TEXT NOT NULL,"
+ "normqualname TEXT PRIMARY KEY NOT NULL,"
+ "rep BLOB NOT NULL);");
+
+ _execDbStatement(
+ db,
+ "CREATE TABLE ClassTable("
+ "classname TEXT NOT NULL,"
+ "normclassname TEXT PRIMARY KEY NOT NULL,"
+ "superclassname TEXT NOT NULL,"
+ "rep BLOB NOT NULL);");
+
+ _execDbStatement(
+ db,
+ "CREATE TABLE ClassAssocTable("
+ "assocclassname TEXT NOT NULL,"
+ "normassocclassname TEXT NOT NULL,"
+ "normfromclassname TEXT NOT NULL,"
+ "normfrompropname TEXT NOT NULL,"
+ "toclassname TEXT NOT NULL,"
+ "normtoclassname TEXT NOT NULL,"
+ "normtopropname TEXT NOT NULL,"
+ "PRIMARY KEY("
+ "normassocclassname, normfrompropname, normtopropname));");
+
+ _execDbStatement(
+ db,
+ "CREATE TABLE InstanceTable("
+ "normclassname TEXT NOT NULL,"
+ "instname TEXT NOT NULL,"
+ "norminstname TEXT PRIMARY KEY NOT NULL,"
+ "rep BLOB NOT NULL);");
+
+ _execDbStatement(
+ db,
+ "CREATE TABLE InstanceAssocTable("
+ "associnstname TEXT NOT NULL,"
+ "normassocinstname TEXT NOT NULL,"
+ "normassocclassname TEXT NOT NULL,"
+ "normfrominstname TEXT NOT NULL,"
+ "normfrompropname TEXT NOT NULL,"
+ "toinstname TEXT NOT NULL,"
+ "normtoclassname TEXT NOT NULL,"
+ "normtopropname TEXT NOT NULL,"
+ "PRIMARY KEY("
+ "normassocinstname, normfrompropname, normtopropname));");
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::_beginTransaction(sqlite3* db)
+{
+ _execDbStatement(db, "BEGIN;");
+}
+
+void SQLiteStore::_commitTransaction(sqlite3* db)
+{
+ _execDbStatement(db, "COMMIT;");
+}
+
+Array<NamespaceDefinition> SQLiteStore::enumerateNameSpaces()
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::enumerateNameSpaces");
+
+ Array<NamespaceDefinition> nameSpaces;
+
+ Array<String> dbFileNames;
+ if (!FileSystem::glob(_repositoryRoot, "*.db", dbFileNames))
+ {
+ throw CannotOpenDirectory(_repositoryRoot);
+ }
+
+ const char* sqlStatement = "SELECT nsname, shareable, updatesallowed, "
+ "parentnsname, remoteinfo FROM NamespaceTable;";
+
+ for (Uint32 i = 0; i < dbFileNames.size(); i++)
+ {
+ AutoPtr<sqlite3, CloseSQLiteDb> db(
+ _openDb((_repositoryRoot + "/" + dbFileNames[i]).getCString()));
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ int rc = sqlite3_step(stmt);
+
+ if (rc == SQLITE_ROW)
+ {
+ NamespaceDefinition nsdef(String(
+ (const Char16*) sqlite3_column_text16(stmt, 0),
+ (Uint32) sqlite3_column_bytes16(stmt, 0) / 2));
+ nsdef.shareable = (Boolean) sqlite3_column_int(stmt, 1);
+ nsdef.updatesAllowed = (Boolean) sqlite3_column_int(stmt, 2);
+ String parentNameSpace = String(
+ (const Char16*) sqlite3_column_text16(stmt, 3),
+ (Uint32) sqlite3_column_bytes16(stmt, 3) / 2);
+ if (parentNameSpace.size())
+ {
+ nsdef.parentNameSpace = parentNameSpace;
+ }
+ nsdef.remoteInfo = String(
+ (const Char16*) sqlite3_column_text16(stmt, 4),
+ (Uint32) sqlite3_column_bytes16(stmt, 4) / 2);
+ nameSpaces.append(nsdef);
+ }
+ else
+ {
+ // There should always be one entry in the table. This namespace
+ // must be corrupt. Skip it.
+ PEG_TRACE((TRC_REPOSITORY, Tracer::LEVEL1,
+ "Corrupt namespace database %s",
+ (const char*) dbFileNames[i].getCString()));
+ }
+ }
+
+ PEG_METHOD_EXIT();
+ return nameSpaces;
+}
+
+void SQLiteStore::createNameSpace(
+ const CIMNamespaceName& nameSpace,
+ Boolean shareable,
+ Boolean updatesAllowed,
+ const String& parentNameSpace)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::createNameSpace");
+
+ String dbPath = _getDbPath(nameSpace);
+
+ if (FileSystem::exists(dbPath))
+ {
+ throw Exception(MessageLoaderParms(
+ "Repository.SQLiteStore.DB_FILE_ALREADY_EXISTS",
+ "Cannot create namespace $0: SQLite database file \"$1\" already "
+ "exists in the repository."));
+ }
+
+ try
+ {
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(dbPath.getCString()));
+
+ _initSchema(db.get());
+
+ const char* sqlStatement =
+ "INSERT INTO NamespaceTable VALUES(?,?,?,?,?);";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String ns = nameSpace.getString();
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt, 1, ns.getChar16Data(), ns.size() * 2, SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_int(stmt, 2, shareable? 1 : 0), db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_int(stmt, 3, updatesAllowed? 1 : 0), db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 4,
+ parentNameSpace.getChar16Data(),
+ parentNameSpace.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ // Online creation of remote namespace is apparently not supported.
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 5,
+ String::EMPTY.getChar16Data(),
+ 0,
+ SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+ }
+ catch (...)
+ {
+ // Do not leave a partially created database file
+ FileSystem::removeFile(dbPath);
+ PEG_METHOD_EXIT();
+ throw;
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::modifyNameSpace(
+ const CIMNamespaceName& nameSpace,
+ Boolean shareable,
+ Boolean updatesAllowed)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::modifyNameSpace");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ // The NamespaceTable contains only a single row, so no WHERE clause is
+ // needed.
+ const char* sqlStatement = "UPDATE NamespaceTable SET shareable=?, "
+ "updatesallowed=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ CHECK_RC_OK(sqlite3_bind_int(stmt, 1, shareable? 1 : 0), db.get());
+ CHECK_RC_OK(sqlite3_bind_int(stmt, 2, updatesAllowed? 1 : 0), db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::deleteNameSpace(const CIMNamespaceName& nameSpace)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteNameSpace");
+
+ String dbPath = _getDbPath(nameSpace);
+
+ if (!FileSystem::removeFile(dbPath))
+ {
+ throw CannotRemoveFile(dbPath);
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+Boolean SQLiteStore::isNameSpaceEmpty(const CIMNamespaceName& nameSpace)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::isNameSpaceEmpty");
+
+ Boolean isEmpty =
+ ((enumerateQualifiers(nameSpace).size() == 0) &&
+ (enumerateClassNames(nameSpace).size() == 0));
+
+ PEG_METHOD_EXIT();
+ return isEmpty;
+}
+
+Array<CIMQualifierDecl> SQLiteStore::enumerateQualifiers(
+ const CIMNamespaceName& nameSpace)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::enumerateQualifiers");
+
+ Array<CIMQualifierDecl> qualifiers;
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT rep FROM QualifierTable;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ Buffer data(
+ (const char*)sqlite3_column_blob(stmt, 0),
+ (Uint32)sqlite3_column_bytes(stmt, 0));
+ CIMQualifierDecl qualifier;
+ _streamer->decode(data, 0, qualifier);
+ qualifiers.append(qualifier);
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+ return qualifiers;
+}
+
+CIMQualifierDecl SQLiteStore::getQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& qualifierName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::getQualifier");
+
+ CIMQualifierDecl qualifier;
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT rep FROM QualifierTable "
+ "WHERE normqualname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String qualname = _getNormalizedName(qualifierName);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ qualname.getChar16Data(),
+ qualname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ int rc;
+ rc = sqlite3_step(stmt);
+
+ if (rc == SQLITE_ROW)
+ {
+ Buffer data(
+ (const char*)sqlite3_column_blob(stmt, 0),
+ (Uint32)sqlite3_column_bytes(stmt, 0));
+ _streamer->decode(data, 0, qualifier);
+ }
+ else
+ {
+ CHECK_RC_DONE(rc, db.get());
+
+ // SQLITE_DONE here means the qualifier is not found
+ PEG_METHOD_EXIT();
+ return CIMQualifierDecl();
+ }
+
+ PEG_METHOD_EXIT();
+ return qualifier;
+}
+
+void SQLiteStore::setQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMQualifierDecl& qualifierDecl)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::setQualifier");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ // Note: This is a relatively inefficient way to determine the existence
+ // of a qualifier, but setting a qualifier is expected to be an infrequent
+ // operation.
+ if (getQualifier(nameSpace, qualifierDecl.getName()).isUninitialized())
+ {
+ // Qualifier does not exist yet; create it
+ const char* sqlStatement =
+ "INSERT INTO QualifierTable VALUES(?,?,?);";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String qualname = qualifierDecl.getName().getString();
+ String normqualname = _getNormalizedName(qualifierDecl.getName());
+ Buffer data;
+ _streamer->encode(data, qualifierDecl);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ qualname.getChar16Data(),
+ qualname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ normqualname.getChar16Data(),
+ normqualname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_blob(
+ stmt, 3, data.getData(), data.size(), SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+ }
+ else
+ {
+ // Qualifier already exists; replace it
+ const char* sqlStatement = "UPDATE QualifierTable "
+ "SET rep=?, qualname=? WHERE normqualname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String qualname = qualifierDecl.getName().getString();
+ String normqualname = _getNormalizedName(qualifierDecl.getName());
+ Buffer data;
+ _streamer->encode(data, qualifierDecl);
+
+ CHECK_RC_OK(
+ sqlite3_bind_blob(
+ stmt, 1, data.getData(), data.size(), SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ qualname.getChar16Data(),
+ qualname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 3,
+ normqualname.getChar16Data(),
+ normqualname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::deleteQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& qualifierName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteQualifier");
+
+ // Note: This is a relatively inefficient way to verify the existence of a
+ // qualifier, but deleting a qualifier is expected to be an infrequent
+ // operation.
+ if (getQualifier(nameSpace, qualifierName).isUninitialized())
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION(
+ CIM_ERR_NOT_FOUND, qualifierName.getString());
+ }
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "DELETE FROM QualifierTable "
+ "WHERE normqualname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String qualname = _getNormalizedName(qualifierName);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ qualname.getChar16Data(),
+ qualname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+Array<Pair<String, String> > SQLiteStore::enumerateClassNames(
+ const CIMNamespaceName& nameSpace)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::enumerateClassNames");
+
+ Array<Pair<String, String> > classList;
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT classname, superclassname "
+ "FROM ClassTable;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ classList.append(Pair<String, String>(
+ String(
+ (const Char16*)sqlite3_column_text16(stmt, 0),
+ (Uint32)sqlite3_column_bytes16(stmt, 0) / 2),
+ String(
+ (const Char16*)sqlite3_column_text16(stmt, 1),
+ (Uint32)sqlite3_column_bytes16(stmt, 1) / 2)));
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+ return classList;
+}
+
+CIMClass SQLiteStore::getClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className,
+ const CIMName& superClassName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::getClass");
+
+ CIMClass cimClass;
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT rep FROM ClassTable "
+ "WHERE normclassname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String classname = _getNormalizedName(className);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ classname.getChar16Data(),
+ classname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ int rc = sqlite3_step(stmt);
+
+ if (rc == SQLITE_ROW)
+ {
+ Buffer data(
+ (const char*)sqlite3_column_blob(stmt, 0),
+ (Uint32)sqlite3_column_bytes(stmt, 0));
+ _streamer->decode(data, 0, cimClass);
+ }
+ else
+ {
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, className.getString());
+ }
+
+ PEG_METHOD_EXIT();
+ return cimClass;
+}
+
+void SQLiteStore::createClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMClass& newClass,
+ const Array<ClassAssociation>& classAssocEntries)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::createClass");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ _beginTransaction(db.get());
+
+ const char* sqlStatement = "INSERT INTO ClassTable VALUES(?,?,?,?);";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String classname = newClass.getClassName().getString();
+ String normclassname = _getNormalizedName(newClass.getClassName());
+ String superclassname = newClass.getSuperClassName().getString();
+ Buffer data;
+ _streamer->encode(data, newClass);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ classname.getChar16Data(),
+ classname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ normclassname.getChar16Data(),
+ normclassname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 3,
+ superclassname.getChar16Data(),
+ superclassname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_blob(stmt, 4, data.getData(), data.size(), SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ // Create the class association entries
+ if (classAssocEntries.size())
+ {
+ _addClassAssociationEntries(db.get(), nameSpace, classAssocEntries);
+ }
+
+ _commitTransaction(db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::modifyClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMClass& modifiedClass,
+ const CIMName& oldSuperClassName,
+ Boolean isAssociation,
+ const Array<ClassAssociation>& classAssocEntries)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::modifyClass");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ _beginTransaction(db.get());
+
+ const char* sqlStatement = "UPDATE ClassTable SET rep=? "
+ "WHERE normclassname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ Buffer data;
+ _streamer->encode(data, modifiedClass);
+ String normclassname = _getNormalizedName(modifiedClass.getClassName());
+
+ CHECK_RC_OK(
+ sqlite3_bind_blob(stmt, 1, data.getData(), data.size(), SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ normclassname.getChar16Data(),
+ normclassname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ //
+ // Update the association entries
+ //
+
+ if (isAssociation)
+ {
+ _removeClassAssociationEntries(
+ db.get(), nameSpace, modifiedClass.getClassName());
+ if (classAssocEntries.size())
+ {
+ _addClassAssociationEntries(db.get(), nameSpace, classAssocEntries);
+ }
+ }
+
+ _commitTransaction(db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::deleteClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className,
+ const CIMName& superClassName,
+ Boolean isAssociation,
+ const Array<CIMNamespaceName>& dependentNameSpaceNames)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteClass");
+
+ // Note: This is a relatively inefficient way to verify the existence of a
+ // class, but deleting a class is expected to be an infrequent operation.
+ CIMClass dummy = getClass(nameSpace, className, superClassName);
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ _beginTransaction(db.get());
+
+ const char* sqlStatement = "DELETE FROM ClassTable "
+ "WHERE normclassname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String normclassname = _getNormalizedName(className);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ normclassname.getChar16Data(),
+ normclassname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ //
+ // Remove association entries
+ //
+
+ if (isAssociation)
+ {
+ _removeClassAssociationEntries(db.get(), nameSpace, className);
+ }
+
+ _commitTransaction(db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+Array<CIMObjectPath> SQLiteStore::enumerateInstanceNamesForClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::enumerateInstanceNamesForClass");
+
+ Array<CIMObjectPath> instanceNames;
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT instname FROM InstanceTable "
+ "WHERE normclassname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String classname = _getNormalizedName(className);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ classname.getChar16Data(),
+ classname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ instanceNames.append(CIMObjectPath(String(
+ (const Char16*)sqlite3_column_text16(stmt, 0),
+ (Uint32)sqlite3_column_bytes16(stmt, 0) / 2)));
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+ return instanceNames;
+}
+
+Array<CIMInstance> SQLiteStore::enumerateInstancesForClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::enumerateInstancesForClass");
+
+ Array<CIMInstance> cimInstances;
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT instname, rep FROM InstanceTable "
+ "WHERE normclassname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String classname = _getNormalizedName(className);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ classname.getChar16Data(),
+ classname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ CIMObjectPath instanceName = CIMObjectPath(String(
+ (const Char16*)sqlite3_column_text16(stmt, 0),
+ (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
+ Buffer data(
+ (const char*)sqlite3_column_blob(stmt, 1),
+ (Uint32)sqlite3_column_bytes(stmt, 1));
+
+ CIMInstance cimInstance;
+ _streamer->decode(data, 0, cimInstance);
+ cimInstance.setPath(instanceName);
+ cimInstances.append(cimInstance);
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+ return cimInstances;
+}
+
+CIMInstance SQLiteStore::getInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::getInstance");
+
+ CIMInstance cimInstance;
+ Boolean foundInstance = false;
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT instname, rep FROM InstanceTable "
+ "WHERE norminstname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String norminstname = instanceName._toStringCanonical();
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ norminstname.getChar16Data(),
+ norminstname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ int rc = sqlite3_step(stmt);
+
+ if (rc == SQLITE_ROW)
+ {
+ Buffer data(
+ (const char*)sqlite3_column_blob(stmt, 1),
+ (Uint32)sqlite3_column_bytes(stmt, 1));
+ _streamer->decode(data, 0, cimInstance);
+ }
+ else
+ {
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
+ }
+
+ PEG_METHOD_EXIT();
+ return cimInstance;
+}
+
+void SQLiteStore::createInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const CIMInstance& cimInstance,
+ const Array<InstanceAssociation>& instAssocEntries)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::createInstance");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ _beginTransaction(db.get());
+
+ const char* sqlStatement = "INSERT INTO InstanceTable VALUES(?,?,?,?);";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String classname = _getNormalizedName(cimInstance.getClassName());
+ String instname = instanceName.toString();
+ String norminstname = instanceName._toStringCanonical();
+ Buffer data;
+ _streamer->encode(data, cimInstance);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ classname.getChar16Data(),
+ classname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ instname.getChar16Data(),
+ instname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 3,
+ norminstname.getChar16Data(),
+ norminstname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_blob(stmt, 4, data.getData(), data.size(), SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ //
+ // Create association entries if an association instance.
+ //
+
+ if (instAssocEntries.size())
+ {
+ _addInstanceAssociationEntries(db.get(), nameSpace, instAssocEntries);
+ }
+
+ _commitTransaction(db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::modifyInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const CIMInstance& cimInstance)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::modifyInstance");
+
+ if (!instanceExists(nameSpace, instanceName))
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
+ }
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "UPDATE InstanceTable SET rep=? "
+ "WHERE norminstname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ Buffer data;
+ _streamer->encode(data, cimInstance);
+ String norminstname = instanceName._toStringCanonical();
+
+ CHECK_RC_OK(
+ sqlite3_bind_blob(stmt, 1, data.getData(), data.size(), SQLITE_STATIC),
+ db.get());
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ norminstname.getChar16Data(),
+ norminstname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::deleteInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::deleteInstance");
+
+ if (!instanceExists(nameSpace, instanceName))
+ {
+ throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
+ }
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ _beginTransaction(db.get());
+
+ const char* sqlStatement = "DELETE FROM InstanceTable "
+ "WHERE norminstname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String norminstname = instanceName._toStringCanonical();
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ norminstname.getChar16Data(),
+ norminstname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db.get());
+
+ //
+ // Delete from association table (if an assocation).
+ //
+
+ _removeInstanceAssociationEntries(db.get(), nameSpace, instanceName);
+
+ _commitTransaction(db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+Boolean SQLiteStore::instanceExists(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "SQLiteStore::instanceExists");
+
+ Boolean foundInstance = false;
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ const char* sqlStatement = "SELECT instname FROM InstanceTable "
+ "WHERE norminstname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement, -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String norminstname = instanceName._toStringCanonical();
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ norminstname.getChar16Data(),
+ norminstname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ int rc = sqlite3_step(stmt);
+
+ if (rc == SQLITE_ROW)
+ {
+ PEG_METHOD_EXIT();
+ return true;
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+ return false;
+}
+
+void SQLiteStore::_addClassAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const Array<ClassAssociation>& classAssocEntries)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::_addClassAssociationEntries");
+
+ const char* sqlStatement =
+ "INSERT INTO ClassAssocTable VALUES(?,?,?,?,?,?,?);";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
+ db);
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ for (Uint32 i = 0; i < classAssocEntries.size(); i++)
+ {
+ String assocclassname =
+ classAssocEntries[i].assocClassName.getString();
+ String normassocclassname = _getNormalizedName(
+ classAssocEntries[i].assocClassName);
+ String normfromclassname = _getNormalizedName(
+ classAssocEntries[i].fromClassName);
+ String normfrompropname = _getNormalizedName(
+ classAssocEntries[i].fromPropertyName);
+ String toclassname =
+ classAssocEntries[i].toClassName.getString();
+ String normtoclassname = _getNormalizedName(
+ classAssocEntries[i].toClassName);
+ String normtopropname = _getNormalizedName(
+ classAssocEntries[i].toPropertyName);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ assocclassname.getChar16Data(),
+ assocclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ normassocclassname.getChar16Data(),
+ normassocclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 3,
+ normfromclassname.getChar16Data(),
+ normfromclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 4,
+ normfrompropname.getChar16Data(),
+ normfrompropname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 5,
+ toclassname.getChar16Data(),
+ toclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 6,
+ normtoclassname.getChar16Data(),
+ normtoclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 7,
+ normtopropname.getChar16Data(),
+ normtopropname.size() * 2,
+ SQLITE_STATIC),
+ db);
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db);
+
+ CHECK_RC_OK(sqlite3_reset(stmt), db);
+
+ CHECK_RC_OK(sqlite3_clear_bindings(stmt), db);
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::_removeClassAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const CIMName& assocClassName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::_removeClassAssociationEntries");
+
+ const char* sqlStatement = "DELETE FROM ClassAssocTable "
+ "WHERE normassocclassname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
+ db);
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String normassocclassname = _getNormalizedName(assocClassName);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ normassocclassname.getChar16Data(),
+ normassocclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db);
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::getClassAssociatorNames(
+ const CIMNamespaceName& nameSpace,
+ const Array<CIMName>& classList,
+ const Array<CIMName>& assocClassList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ const String& resultRole,
+ Array<String>& associatorNames)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::getClassAssociatorNames");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ String sqlStatement =
+ "SELECT DISTINCT toclassname FROM ClassAssocTable WHERE (";
+
+ // Match "from" class name
+ for (Uint32 i = 0; i < classList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normfromclassname=?");
+ }
+ sqlStatement.append(')');
+
+ // Match role
+ if (role.size())
+ {
+ sqlStatement.append(" AND normfrompropname=?");
+ }
+
+ // Match resultRole
+ if (resultRole.size())
+ {
+ sqlStatement.append(" AND normtopropname=?");
+ }
+
+ // Match association class name
+ if (assocClassList.size())
+ {
+ sqlStatement.append(" AND (");
+
+ for (Uint32 i = 0; i < assocClassList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normassocclassname=?");
+ }
+
+ sqlStatement.append(')');
+ }
+
+ // Match result class name
+ if (resultClassList.size())
+ {
+ sqlStatement.append(" AND (");
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normtoclassname=?");
+ }
+
+ sqlStatement.append(')');
+ }
+
+ sqlStatement.append(';');
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ int bindIndex = 1;
+
+ for (Uint32 i = 0; i < classList.size(); i++)
+ {
+ String normfromclassname = _getNormalizedName(classList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfromclassname.getChar16Data(),
+ normfromclassname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ if (role.size())
+ {
+ String normfrompropname = _getNormalizedName(CIMNameUnchecked(role));
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfrompropname.getChar16Data(),
+ normfrompropname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ if (resultRole.size())
+ {
+ String normtopropname =
+ _getNormalizedName(CIMNameUnchecked(resultRole));
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normtopropname.getChar16Data(),
+ normtopropname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ for (Uint32 i = 0; i < assocClassList.size(); i++)
+ {
+ String normassocclassname = _getNormalizedName(assocClassList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normassocclassname.getChar16Data(),
+ normassocclassname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ String normtopropname = _getNormalizedName(resultClassList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normtopropname.getChar16Data(),
+ normtopropname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ associatorNames.append(String(
+ (const Char16*)sqlite3_column_text16(stmt, 0),
+ (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::getClassReferenceNames(
+ const CIMNamespaceName& nameSpace,
+ const Array<CIMName>& classList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ Array<String>& referenceNames)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::getClassReferenceNames");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ String sqlStatement =
+ "SELECT DISTINCT assocclassname FROM ClassAssocTable WHERE (";
+
+ // Match "from" class name
+ for (Uint32 i = 0; i < classList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normfromclassname=?");
+ }
+ sqlStatement.append(')');
+
+ // Match role
+ if (role.size())
+ {
+ sqlStatement.append(" AND normfrompropname=?");
+ }
+
+ // Match result class name
+ if (resultClassList.size())
+ {
+ sqlStatement.append(" AND (");
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normassocclassname=?");
+ }
+
+ sqlStatement.append(')');
+ }
+
+ sqlStatement.append(';');
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ int bindIndex = 1;
+
+ for (Uint32 i = 0; i < classList.size(); i++)
+ {
+ String normfromclassname = _getNormalizedName(classList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfromclassname.getChar16Data(),
+ normfromclassname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ if (role.size())
+ {
+ String normfrompropname = _getNormalizedName(CIMNameUnchecked(role));
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfrompropname.getChar16Data(),
+ normfrompropname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ String normassocclassname = _getNormalizedName(resultClassList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normassocclassname.getChar16Data(),
+ normassocclassname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ referenceNames.append(String(
+ (const Char16*)sqlite3_column_text16(stmt, 0),
+ (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::_addInstanceAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const Array<InstanceAssociation>& instanceAssocEntries)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::_addInstanceAssociationEntries");
+
+ const char* sqlStatement =
+ "INSERT INTO InstanceAssocTable VALUES(?,?,?,?,?,?,?,?);";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
+ db);
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ for (Uint32 i = 0; i < instanceAssocEntries.size(); i++)
+ {
+ String associnstname =
+ instanceAssocEntries[i].assocInstanceName;
+ // Note: This converts a String to a CIMObjectPath and back to a String
+ String normassocinstname = CIMObjectPath(
+ instanceAssocEntries[i].assocInstanceName)._toStringCanonical();
+ String normassocclassname = _getNormalizedName(
+ instanceAssocEntries[i].assocClassName);
+ // Note: This converts a String to a CIMObjectPath and back to a String
+ String normfrominstname = CIMObjectPath(
+ instanceAssocEntries[i].fromInstanceName)._toStringCanonical();
+ String normfrompropname = _getNormalizedName(
+ instanceAssocEntries[i].fromPropertyName);
+ String toinstname =
+ instanceAssocEntries[i].toInstanceName;
+ String normtoclassname = _getNormalizedName(
+ instanceAssocEntries[i].toClassName);
+ String normtopropname = _getNormalizedName(
+ instanceAssocEntries[i].toPropertyName);
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ associnstname.getChar16Data(),
+ associnstname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 2,
+ normassocinstname.getChar16Data(),
+ normassocinstname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 3,
+ normassocclassname.getChar16Data(),
+ normassocclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 4,
+ normfrominstname.getChar16Data(),
+ normfrominstname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 5,
+ normfrompropname.getChar16Data(),
+ normfrompropname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 6,
+ toinstname.getChar16Data(),
+ toinstname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 7,
+ normtoclassname.getChar16Data(),
+ normtoclassname.size() * 2,
+ SQLITE_STATIC),
+ db);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 8,
+ normtopropname.getChar16Data(),
+ normtopropname.size() * 2,
+ SQLITE_STATIC),
+ db);
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db);
+
+ CHECK_RC_OK(sqlite3_reset(stmt), db);
+
+ CHECK_RC_OK(sqlite3_clear_bindings(stmt), db);
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::_removeInstanceAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& assocInstanceName)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::_removeInstanceAssociationEntries");
+
+ const char* sqlStatement = "DELETE FROM InstanceAssocTable "
+ "WHERE normassocinstname=?;";
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db, sqlStatement, -1, &stmt, 0),
+ db);
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String associnstname = assocInstanceName._toStringCanonical();
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ 1,
+ associnstname.getChar16Data(),
+ associnstname.size() * 2,
+ SQLITE_STATIC),
+ db);
+
+ CHECK_RC_DONE(sqlite3_step(stmt), db);
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::getInstanceAssociatorNames(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const Array<CIMName>& assocClassList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ const String& resultRole,
+ Array<String>& associatorNames)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::getInstanceAssociatorNames");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ String sqlStatement = "SELECT DISTINCT toinstname "
+ "FROM InstanceAssocTable WHERE normfrominstname=?";
+
+ // Match role
+ if (role.size())
+ {
+ sqlStatement.append(" AND normfrompropname=?");
+ }
+
+ // Match resultRole
+ if (resultRole.size())
+ {
+ sqlStatement.append(" AND normtopropname=?");
+ }
+
+ // Match association class name
+ if (assocClassList.size())
+ {
+ sqlStatement.append(" AND (");
+
+ for (Uint32 i = 0; i < assocClassList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normassocclassname=?");
+ }
+
+ sqlStatement.append(')');
+ }
+
+ // Match result class name
+ if (resultClassList.size())
+ {
+ sqlStatement.append(" AND (");
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normtoclassname=?");
+ }
+
+ sqlStatement.append(')');
+ }
+
+ sqlStatement.append(';');
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String normfrominstname = instanceName._toStringCanonical();
+ int bindIndex = 1;
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfrominstname.getChar16Data(),
+ normfrominstname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ if (role.size())
+ {
+ String normfrompropname = _getNormalizedName(CIMNameUnchecked(role));
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfrompropname.getChar16Data(),
+ normfrompropname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ if (resultRole.size())
+ {
+ String normtopropname =
+ _getNormalizedName(CIMNameUnchecked(resultRole));
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normtopropname.getChar16Data(),
+ normtopropname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ for (Uint32 i = 0; i < assocClassList.size(); i++)
+ {
+ String normassocclassname = _getNormalizedName(assocClassList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normassocclassname.getChar16Data(),
+ normassocclassname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ String normtoclassname = _getNormalizedName(resultClassList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normtoclassname.getChar16Data(),
+ normtoclassname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ associatorNames.append(String(
+ (const Char16*)sqlite3_column_text16(stmt, 0),
+ (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+void SQLiteStore::getInstanceReferenceNames(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ Array<String>& referenceNames)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "SQLiteStore::getInstanceReferenceNames");
+
+ AutoPtr<sqlite3, CloseSQLiteDb> db(_openDb(nameSpace));
+
+ String sqlStatement = "SELECT DISTINCT associnstname "
+ "FROM InstanceAssocTable WHERE normfrominstname=?";
+
+ // Match role
+ if (role.size())
+ {
+ sqlStatement.append(" AND normfrompropname=?");
+ }
+
+ // Match result class name
+ if (resultClassList.size())
+ {
+ sqlStatement.append(" AND (");
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ if (i > 0)
+ {
+ sqlStatement.append(" OR ");
+ }
+
+ sqlStatement.append("normassocclassname=?");
+ }
+
+ sqlStatement.append(')');
+ }
+
+ sqlStatement.append(';');
+
+ sqlite3_stmt* stmt = 0;
+ CHECK_RC_OK(
+ sqlite3_prepare_v2(db.get(), sqlStatement.getCString(), -1, &stmt, 0),
+ db.get());
+ AutoPtr<sqlite3_stmt, FinalizeSQLiteStatement> stmtDestroyer(stmt);
+
+ String normfrominstname = instanceName._toStringCanonical();
+ int bindIndex = 1;
+
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfrominstname.getChar16Data(),
+ normfrominstname.size() * 2,
+ SQLITE_STATIC),
+ db.get());
+
+ if (role.size())
+ {
+ String normfrompropname = _getNormalizedName(CIMNameUnchecked(role));
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normfrompropname.getChar16Data(),
+ normfrompropname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ for (Uint32 i = 0; i < resultClassList.size(); i++)
+ {
+ String normassocclassname = _getNormalizedName(resultClassList[i]);
+ CHECK_RC_OK(
+ sqlite3_bind_text16(
+ stmt,
+ bindIndex++,
+ normassocclassname.getChar16Data(),
+ normassocclassname.size() * 2,
+ SQLITE_TRANSIENT),
+ db.get());
+ }
+
+ int rc;
+ while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
+ {
+ referenceNames.append(String(
+ (const Char16*)sqlite3_column_text16(stmt, 0),
+ (Uint32)sqlite3_column_bytes16(stmt, 0) / 2));
+ }
+
+ CHECK_RC_DONE(rc, db.get());
+
+ PEG_METHOD_EXIT();
+}
+
+PEGASUS_NAMESPACE_END
diff --git a/src/Pegasus/Repository/SQLiteStore.h b/src/Pegasus/Repository/SQLiteStore.h
new file mode 100644
index 0000000..33e06bf
--- /dev/null
+++ b/src/Pegasus/Repository/SQLiteStore.h
@@ -0,0 +1,231 @@
+//%2006////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
+// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
+// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation, The Open Group.
+// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
+// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; VERITAS Software Corporation; The Open Group.
+// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
+// EMC Corporation; Symantec Corporation; The Open Group.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
+// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//==============================================================================
+//
+//%/////////////////////////////////////////////////////////////////////////////
+
+#ifndef Pegasus_SQLiteStore_h
+#define Pegasus_SQLiteStore_h
+
+#include <Pegasus/Common/Config.h>
+#include <Pegasus/Common/CommonUTF.h>
+#include <Pegasus/Repository/PersistentStore.h>
+#include <Pegasus/Repository/Linkage.h>
+
+#include <sqlite3.h>
+
+PEGASUS_NAMESPACE_BEGIN
+
+class PEGASUS_REPOSITORY_LINKAGE SQLiteStore : public PersistentStore
+{
+public:
+
+ static Boolean isExistingRepository(const String& repositoryRoot);
+
+ SQLiteStore(
+ const String& repositoryRoot,
+ ObjectStreamer* streamer);
+
+ ~SQLiteStore();
+
+ Boolean storeCompleteClassDefinitions()
+ {
+ return false;
+ }
+
+ Array<NamespaceDefinition> enumerateNameSpaces();
+ void createNameSpace(
+ const CIMNamespaceName& nameSpace,
+ Boolean shareable,
+ Boolean updatesAllowed,
+ const String& parentNameSpace);
+ void modifyNameSpace(
+ const CIMNamespaceName& nameSpace,
+ Boolean shareable,
+ Boolean updatesAllowed);
+ void deleteNameSpace(const CIMNamespaceName& nameSpace);
+ Boolean isNameSpaceEmpty(const CIMNamespaceName& nameSpace);
+
+ Array<CIMQualifierDecl> enumerateQualifiers(
+ const CIMNamespaceName& nameSpace);
+ /**
+ Gets a qualifier declaration for a specified qualifier name in a
+ specified namespace. Returns an uninitialized object if the qualifier
+ is not found.
+ */
+ CIMQualifierDecl getQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& qualifierName);
+ void setQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMQualifierDecl& qualifierDecl);
+ void deleteQualifier(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& qualifierName);
+
+ Array<Pair<String, String> > enumerateClassNames(
+ const CIMNamespaceName& nameSpace);
+ CIMClass getClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className,
+ const CIMName& superClassName);
+ void createClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMClass& newClass,
+ const Array<ClassAssociation>& classAssocEntries);
+ void modifyClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMClass& modifiedClass,
+ const CIMName& oldSuperClassName,
+ Boolean isAssociation,
+ const Array<ClassAssociation>& classAssocEntries);
+ void deleteClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className,
+ const CIMName& superClassName,
+ Boolean isAssociation,
+ const Array<CIMNamespaceName>& dependentNameSpaceNames);
+ Array<CIMObjectPath> enumerateInstanceNamesForClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className);
+ Array<CIMInstance> enumerateInstancesForClass(
+ const CIMNamespaceName& nameSpace,
+ const CIMName& className);
+ CIMInstance getInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName);
+ void createInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const CIMInstance& cimInstance,
+ const Array<InstanceAssociation>& instAssocEntries);
+ void modifyInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const CIMInstance& cimInstance);
+ void deleteInstance(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName);
+ Boolean instanceExists(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName);
+
+ void getClassAssociatorNames(
+ const CIMNamespaceName& nameSpace,
+ const Array<CIMName>& classList,
+ const Array<CIMName>& assocClassList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ const String& resultRole,
+ Array<String>& associatorNames);
+ void getClassReferenceNames(
+ const CIMNamespaceName& nameSpace,
+ const Array<CIMName>& classList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ Array<String>& referenceNames);
+
+ void getInstanceAssociatorNames(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const Array<CIMName>& assocClassList,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ const String& resultRole,
+ Array<String>& associatorNames);
+ void getInstanceReferenceNames(
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& instanceName,
+ const Array<CIMName>& resultClassList,
+ const String& role,
+ Array<String>& referenceNames);
+
+private:
+
+ sqlite3* _openDb(const char* fileName);
+ sqlite3* _openDb(const CIMNamespaceName& nameSpace);
+
+ void _execDbStatement(
+ sqlite3* db,
+ const char* sqlStatement);
+
+ void _initSchema(sqlite3* db);
+
+ void _beginTransaction(sqlite3* db);
+ void _commitTransaction(sqlite3* db);
+
+ String _getNormalizedName(const CIMName& className)
+ {
+ String cn = className.getString();
+ cn.toLower();
+ return cn;
+ }
+
+ String _getDbPath(const CIMNamespaceName& nameSpace)
+ {
+ String dbFileName = nameSpace.getString();
+ dbFileName.toLower();
+
+ for (Uint32 i = 0; i < dbFileName.size(); i++)
+ {
+ if (dbFileName[i] == '/')
+ {
+ dbFileName[i] = '#';
+ }
+ }
+
+ return _repositoryRoot + "/" + escapeStringEncoder(dbFileName) + ".db";
+ }
+
+ void _addClassAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const Array<ClassAssociation>& classAssocEntries);
+ void _removeClassAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const CIMName& assocClassName);
+
+ void _addInstanceAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const Array<InstanceAssociation>& instanceAssocEntries);
+ void _removeInstanceAssociationEntries(
+ sqlite3* db,
+ const CIMNamespaceName& nameSpace,
+ const CIMObjectPath& assocInstanceName);
+
+ String _repositoryRoot;
+ ObjectStreamer* _streamer;
+};
+
+PEGASUS_NAMESPACE_END
+
+#endif /* Pegasus_SQLiteStore_h */
diff --git a/src/Pegasus/msg/Server/pegasusServer_en.txt b/src/Pegasus/msg/Server/pegasusServer_en.txt
index e9c5161..0d9aeab 100644
--- a/src/Pegasus/msg/Server/pegasusServer_en.txt
+++ b/src/Pegasus/msg/Server/pegasusServer_en.txt
@@ -7196,7 +7196,6 @@ CIM server listening on HTTPS port {0}."}
*/
Server.ProviderRegistrationManager.ProviderManagerMap.MISSING_GET_IFC_VERSIONS:string {"PGS21203: Provider Manager {0} does not contain expected function 'getProviderManagerInterfaceVersions'."}
-
/**
* @note PGS21204
* Substitution {0} is a file name (a string)
@@ -7205,6 +7204,32 @@ CIM server listening on HTTPS port {0}."}
*/
Server.ProviderRegistrationManager.ProviderManagerMap.MISSING_GET_PG_VERSION:string {"PGS21204: Library {0} does not contain expected function 'getPegasusVersion'."}
+
+ // ==========================================================
+ // Messages for SQLiteStore
+ // Please use message prefix "PGS21400 - PGS21599"
+ // ==========================================================
+
+ /**
+ * @note PGS21400
+ * Substitution {0} is a file name (a string)
+ */
+ Repository.SQLiteStore.DB_OPEN_ERROR:string {"PGS21400: Failed to open repository SQLite database file ''{0}''."}
+
+ /**
+ * @note PGS21401
+ * Substitution {0} is an integer error code
+ * Substitution {1} is an error message (a string)
+ */
+ Repository.SQLiteStore.DB_OP_ERROR:string {"PGS21401: Repository SQLite database operation failed with error {0}: {1}"}
+
+ /**
+ * @note PGS21402
+ * Substitution {0} is a namespace name (a string)
+ * Substitution {1} is a file path (a string)
+ */
+ Repository.SQLiteStore.DB_FILE_ALREADY_EXISTS:string {"PGS21402: Cannot create namespace {0}: SQLite database file ''{1}'' already exists in the repository."}
+
// ==============================================================================
// END OF RESOURCE BUNDLE
// DO NOT ADD MESSAGES AFTER THE FOLLOWING '}'