[mapguide-commits] r6853 - in branches/2.4/MgDev/Desktop: MapViewer MgDesktop/Services MgDesktop/Services/Feature UnitTest
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Thu Jul 5 08:27:56 PDT 2012
Author: jng
Date: 2012-07-05 08:27:56 -0700 (Thu, 05 Jul 2012)
New Revision: 6853
Modified:
branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionPool.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/GwsConnectionPool.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h
branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp
branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h
Log:
mg-desktop updates:
- #2057: Fix NullReferenceException on mouse wheel scrolling when no map is loaded
- #2055: Clear existing selection before selection rendering whether a selection is made or not
- #2054: Fix GetClasses and GetClassDefinition to work with Extended Feature Classes
- Extract out the connection booting and cache flushing code into a separate MgdResourceService::ReleasePotentialLocks() method
- Fix crashy behaviour in Release() in our GwsConnectionPool implementation. Returning a value from a member to a disposed pointer isn't exactly a good idea.
Modified: branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs 2012-07-05 15:27:56 UTC (rev 6853)
@@ -2309,7 +2309,12 @@
sw.Stop();
Trace.TraceInformation("Selection processing completed in {0}ms", sw.ElapsedMilliseconds);
#endif
-
+ //This selection may result in nothing, so we invalidate the selection image beforehand
+ if (_selectionImage != null)
+ {
+ _selectionImage.Dispose();
+ _selectionImage = null;
+ }
RenderSelection(true); //This is either async or queued up. Either way do this before firing off selection changed
var handler = this.SelectionChanged;
if (handler != null)
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionPool.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionPool.h 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoConnectionPool.h 2012-07-05 15:27:56 UTC (rev 6853)
@@ -23,7 +23,7 @@
STRING ProviderName;
};
-class MgFdoConnectionPool
+class MG_DESKTOP_API MgFdoConnectionPool //Needs to be exported for unit testing code
{
public:
static void Initialize(MgConfiguration* config);
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/GwsConnectionPool.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/GwsConnectionPool.cpp 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/GwsConnectionPool.cpp 2012-07-05 15:27:56 UTC (rev 6853)
@@ -55,9 +55,11 @@
{
m_iRefCount --;
assert (m_iRefCount >= 0);
- if (m_iRefCount == 0)
- Dispose ();
- return m_iRefCount;
+ if (0 != m_iRefCount)
+ return m_iRefCount;
+
+ Dispose ();
+ return 0;
}
void MgGwsConnectionPool::Dispose ()
{
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp 2012-07-05 15:27:56 UTC (rev 6853)
@@ -1382,7 +1382,7 @@
MgFeatureSchemaCollection* MgdFeatureService::DescribeSchema(MgResourceIdentifier* resource,
CREFSTRING schemaName,
- MgStringCollection* classNames,
+ MgStringCollection* findClassNames,
bool serialize)
{
CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdFeatureService::DescribeSchema");
@@ -1392,8 +1392,38 @@
MG_FEATURE_SERVICE_TRY()
MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
- fsCollection = cache->GetSchemas(resource, schemaName, classNames, serialize);
+ fsCollection = cache->GetSchemas(resource, schemaName, findClassNames, serialize);
+ Ptr<MgFeatureSourceCacheItem> fsCache = cache->GetFeatureSource(resource);
+ MdfModel::FeatureSource* featureSource = fsCache->Get();
+ CHECKNULL(featureSource, L"MgdFeatureService::DescribeSchema");
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgdFeatureService::DescribeSchema");
+ int extensionCount = extensions->GetCount();
+
+ //Weed out extended class names because FDO won't know anything about them
+ Ptr<MgStringCollection> classNames;
+ if (NULL != findClassNames)
+ {
+ classNames = new MgStringCollection();
+ for (INT32 i = 0; i < findClassNames->GetCount(); i++)
+ {
+ STRING clsName = findClassNames->GetItem(i);
+ bool bIsExtendedClassName = false;
+ for (INT32 j = 0; j < extensionCount; j++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgdFeatureService::DescribeSchema");
+ STRING extName = (STRING)extension->GetName();
+ if (clsName == extName)
+ bIsExtendedClassName = true;
+ }
+
+ if (!bIsExtendedClassName)
+ classNames->Add(clsName);
+ }
+ }
+
if (NULL == fsCollection.p)
{
fsCollection = new MgFeatureSchemaCollection();
@@ -1409,7 +1439,6 @@
//
// A new MgFeatureSchema needs to be created for each primary schema in FDO schemas.
//
-
Ptr<MgFeatureSchema> schema;
Ptr<MgClassDefinitionCollection> classCol;
@@ -1459,15 +1488,6 @@
//
// A new MgClassDefinition needs to be created for each extension and added to the MgClassCollection
//
-
- Ptr<MgFeatureSourceCacheItem> fsCache = cache->GetFeatureSource(resource);
-
- MdfModel::FeatureSource* featureSource = fsCache->Get();
- CHECKNULL(featureSource, L"MgdFeatureService::DescribeSchema");
- MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
- CHECKNULL(extensions, L"MgdFeatureService::DescribeSchema");
- int extensionCount = extensions->GetCount();
-
for (int i = 0; i < extensionCount; i++)
{
Ptr<MgClassDefinition> extClassDefinition;
@@ -1698,39 +1718,27 @@
mpdc->Add(propDef);
}
}
-
break;
-
} // end loop thru secondary class collection
-
break;
-
} // end loop thru secondary schemas
}
else
{
throw new MgConnectionFailedException(L"MgdFeatureService::DescribeSchema", __LINE__, __WFILE__, NULL, L"", NULL);
}
-
} // end if (NULL != secFeatureSource)
-
} // end loop thru all attribute relates (joins)
-
if (!extensionName.empty())
{
extClassDefinition->SetName(extensionName);
}
-
// Add the extension class definition to the MgClassDefinitionCollection
classCol->Add(extClassDefinition);
-
} // Repeat for all extensions
-
// Add the schema to the MgFeatureSchemaCollection
fsCollection->Add(schema);
-
} // End loop thru all schemas
-
cache->SetSchemas(resource, schemaName, classNames, serialize, fsCollection.p);
}
else
@@ -5636,6 +5644,8 @@
Ptr<MgFeatureConnection> connWrap = new MgFeatureConnection(resource);
FdoPtr<FdoIConnection> conn = connWrap->GetConnection();
+ STRING theSchemaName = schemaName;
+
if (SupportsPartialSchemaDiscovery(conn))
{
FdoPtr<FdoIGetClassNames> fetch = (FdoIGetClassNames*)conn->CreateCommand(FdoCommandType_GetClassNames);
@@ -5671,6 +5681,49 @@
classNames = names;
}
+ //In case an empty schema name was specified, get the schema name
+ //from the first result.
+ if (theSchemaName.empty())
+ {
+ INT32 clsCount = classNames->GetCount();
+ if (clsCount > 0)
+ {
+ for (INT32 i = 0; i < clsCount; i++)
+ {
+ STRING qn = classNames->GetItem(i);
+ STRING sn;
+ STRING cn;
+ MgUtil::ParseQualifiedClassName(qn, sn, cn);
+
+ theSchemaName = sn;
+ break;
+ }
+ }
+ }
+
+ MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
+ // Add extended feature class names
+ Ptr<MgFeatureSourceCacheItem> fsCache = cache->GetFeatureSource(resource);
+ MdfModel::FeatureSource* featureSource = fsCache->Get();
+ CHECKNULL(featureSource, L"MgdFeatureService::GetClasses");
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgdFeatureService::GetClasses");
+ int extensionCount = extensions->GetCount();
+ for (int i = 0; i < extensionCount; i++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgdFeatureService::GetClasses");
+
+ // Get the extension name
+ STRING extensionName = (STRING)extension->GetName();
+
+ STRING extendedClassName = theSchemaName;
+ extendedClassName += L":";
+ extendedClassName += extensionName;
+
+ classNames->Add(extendedClassName);
+ }
+
// Successful operation
MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/FeatureService.h 2012-07-05 15:27:56 UTC (rev 6853)
@@ -272,7 +272,7 @@
CREFSTRING coordinateSystem,
bool withLock,
bool asScrollable);
-
+
bool ContainsUdf(MgFeatureConnection* conn, FdoExpression* expression);
bool IsCustomFunction(FdoFunction* fdoFunc);
MgReader* GetCustomReader(MgReader* reader, FdoFunction* customFunc, CREFSTRING propertyName);
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp 2012-07-05 15:27:56 UTC (rev 6853)
@@ -2017,8 +2017,9 @@
TransformCacheMap transformCache;
MG_TRY()
-
+#ifdef _DEBUG
ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): ** START **\n")));
+#endif
if (NULL == map || (NULL == geometry && featureFilter.empty()))
throw new MgNullArgumentException(L"MgServerRenderingService.RenderForSelection", __LINE__, __WFILE__, NULL, L"", NULL);
@@ -2102,9 +2103,9 @@
{
//find the layer we need to select features from
Ptr<MgLayerBase> layer = layers->GetItem(p);
-
+ #ifdef _DEBUG
ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): Layer: %W Selectable:%W Visible: %W\n"), layer->GetName().c_str(), layer->GetSelectable()? L"True" : L"False", layer->IsVisibleAtScale(scale)? L"True" : L"False"));
-
+ #endif
//do this first - this check is fast
if (bOnlySelectableLayers && !layer->GetSelectable())
continue;
@@ -2139,8 +2140,9 @@
//we can only do geometric query selection for vector layers
if (vl)
{
+ #ifdef _DEBUG
ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): Layer: %W Vector Layer\n"), layer->GetName().c_str()));
-
+ #endif
//check to see if we want even layers that aren't visible at the current scale
if (!bOnlyVisibleLayers)
{
@@ -2370,7 +2372,9 @@
}
selRenderer->EndMap();
+#ifdef _DEBUG
ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): ** END **\n")));
+#endif
MG_CATCH(L"MgServerRenderingService.RenderForSelection")
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp 2012-07-05 15:27:56 UTC (rev 6853)
@@ -298,16 +298,8 @@
if (NULL != content)
{
Ptr<MgByteSink> sink = new MgByteSink(content);
- sink->ToFile(path);
-
- if (resource->GetResourceType() == MgResourceType::FeatureSource)
- {
- //Invalidate any cached information
- MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
- cache->RemoveEntry(resource);
- //Boot pooled connections
- MgFdoConnectionPool::PurgeCachedConnections(resource);
- }
+ sink->ToFile(path);
+ ReleasePotentialLocks(resource);
}
// Successful operation
@@ -344,26 +336,8 @@
CHECKARGUMENTNULL(resource, L"MgdResourceService::DeleteResource");
if (ResourceExists(resource))
{
- if (resource->GetResourceType() == MgResourceType::FeatureSource)
- {
- //Invalidate any cached information
- MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
- cache->RemoveEntry(resource);
- //Boot pooled connections to ensure no locks are held (technically,
- //the pooled connections are closed, but just to play safe)
- MgFdoConnectionPool::PurgeCachedConnections(resource);
- }
- else if (resource->GetResourceType() == MgResourceType::Folder)
- {
- //TODO: We obviously need a fine-grained version instead of going nuclear
- MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
- cache->Clear();
- //Boot pooled connections to ensure no locks are held (technically,
- //the pooled connections are closed, but just to play safe)
- MgFdoConnectionPool::PurgeCachedConnectionsUnderFolder(resource);
- }
-
- STRING contentPath = ResolveContentPath(resource);
+ ReleasePotentialLocks(resource);
+ STRING contentPath = ResolveContentPath(resource);
STRING dataPath = ResolveDataPath(resource);
if (MgFileUtil::IsFile(contentPath))
{
@@ -400,6 +374,27 @@
MG_RESOURCE_SERVICE_THROW()
}
+void MgdResourceService::ReleasePotentialLocks(MgResourceIdentifier* resource)
+{
+ CHECKARGUMENTNULL(resource, L"MgdResourceService::DeleteResource");
+ if (resource->GetResourceType() == MgResourceType::FeatureSource)
+ {
+ //Invalidate any cached information
+ MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
+ cache->RemoveEntry(resource);
+ //Boot pooled connections to ensure no locks are held
+ MgFdoConnectionPool::PurgeCachedConnections(resource);
+ }
+ else if (resource->GetResourceType() == MgResourceType::Folder)
+ {
+ //TODO: We obviously need a fine-grained version instead of going nuclear
+ MgFeatureServiceCache* cache = MgFeatureServiceCache::GetInstance();
+ cache->Clear();
+ //Boot pooled connections to ensure no locks are held
+ MgFdoConnectionPool::PurgeCachedConnectionsUnderFolder(resource);
+ }
+}
+
void MgdResourceService::CopyResource(MgResourceIdentifier* sourceResource, MgResourceIdentifier* destResource, bool overwrite)
{
MG_LOG_OPERATION_MESSAGE(L"CopyResource");
@@ -728,6 +723,7 @@
if (dataName.empty())
throw new MgNullArgumentException(L"MgdResourceService::DeleteResourceData", __LINE__, __WFILE__, NULL, L"", NULL);
+ ReleasePotentialLocks(resource);
STRING path = ResolveDataPath(resource);
path += dataName;
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.h 2012-07-05 15:27:56 UTC (rev 6853)
@@ -97,6 +97,7 @@
virtual void Dispose() { delete this; }
private:
+ void ReleasePotentialLocks(MgResourceIdentifier* resource);
static bool ListDirectories(MgStringCollection* directoryNames, CREFSTRING path);
void WriteResourceFolderEntry(REFSTRING xml, INT32 maxDepth, STRING type, MgResourceIdentifier* resId, CREFSTRING enumeratedFolderId = L"");
void WriteResourceDocumentEntry(REFSTRING xml, MgResourceIdentifier* resId);
@@ -105,6 +106,7 @@
STRING m_libraryDataPath;
STRING m_sessionContentPath;
STRING m_sessionDataPath;
+ STRING m_schemaPath;
};
#endif
\ No newline at end of file
Modified: branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.cpp 2012-07-05 15:27:56 UTC (rev 6853)
@@ -17,6 +17,7 @@
#include "Services/Feature/FeatureUtil.h"
#include "MgDesktop.h"
+#include "Services/Feature/FdoConnectionPool.h"
#include "TestFeatureService.h"
#include "CppUnitExtensions.h"
#include "Fdo.h"
@@ -261,7 +262,18 @@
__LINE__, __WFILE__, NULL, L"", NULL);
}
- /*
+
+#ifdef DEBUG
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\nConnection Pool status: \n\n")));
+ std::vector<PoolCacheEntry*> entries;
+ MgFdoConnectionPool::GetCacheInfo(entries);
+ for (std::vector<PoolCacheEntry*>::iterator it = entries.begin(); it != entries.end(); it++)
+ {
+ STRING resId = (*it)->ResourceId;
+ ACE_DEBUG((LM_INFO, ACE_TEXT(" - %W (%d Open, %d Closed)\n"), resId.c_str(), (*it)->OpenCount, (*it)->ClosedCount));
+ }
+#endif
+
// delete the feature sources definition
Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/Sheboygan_Parcels.FeatureSource");
pService->DeleteResource(fsres1);
@@ -283,9 +295,12 @@
Ptr<MgResourceIdentifier> fsres7 = new MgResourceIdentifier(L"Library://UnitTests/Data/Sheboygan_Parcels_Writable.FeatureSource");
pService->DeleteResource(fsres7);
- */
- Ptr<MgResourceIdentifier> folder = new MgResourceIdentifier(L"Library://UnitTests/");
- pService->DeleteResource(folder);
+
+ Ptr<MgResourceIdentifier> fsres8 = new MgResourceIdentifier(L"Library://UnitTests/Data/FdoJoin.FeatureSource");
+ pService->DeleteResource(fsres8);
+
+ //Ptr<MgResourceIdentifier> folder = new MgResourceIdentifier(L"Library://UnitTests/");
+ //pService->DeleteResource(folder);
}
catch (MgException* e)
{
@@ -2604,6 +2619,125 @@
///----------------------------------------------------------------------------
/// Test Case Description:
///
+/// This test case exercises schema description APIs against a feature source
+/// with Extended Feature Classes
+///----------------------------------------------------------------------------
+void TestFeatureService::TestCase_ExtendedFeatureClass()
+{
+ try
+ {
+ Ptr<MgServiceFactory> fact = new MgServiceFactory();
+ Ptr<MgFeatureService> pService = dynamic_cast<MgFeatureService*>(fact->CreateService(MgServiceType::FeatureService));
+ if (pService == 0)
+ {
+ throw new MgServiceNotAvailableException(L"TestFeatureService.TestCase_ExtendedFeatureClass",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ Ptr<MgResourceIdentifier> lFeatureSource = new MgResourceIdentifier(L"Library://UnitTests/Data/TestChainedInner1ToManyJoin.FeatureSource");
+
+ Ptr<MgFeatureReader> reader = pService->SelectFeatures(lFeatureSource, L"Ext1", NULL);
+
+ Ptr<MgFeatureSchemaCollection> schemas;
+ Ptr<MgFeatureSchema> schema;
+ //With GetClasses
+ Ptr<MgStringCollection> classNames = pService->GetClasses(lFeatureSource, L"");
+ CPPUNIT_ASSERT(classNames->GetCount() > 0);
+ bool bFound = false;
+ for (INT32 i = 0; i < classNames->GetCount(); i++)
+ {
+ STRING name = classNames->GetItem(i);
+ if (name.find(L"Ext1") != STRING::npos)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ CPPUNIT_ASSERT(bFound);
+
+ //With 1st variation of DescribeSchema()
+ schemas = pService->DescribeSchema(lFeatureSource, L"");
+ CPPUNIT_ASSERT(NULL != schemas.p);
+ CPPUNIT_ASSERT(1 == schemas->GetCount());
+ schema = schemas->GetItem(0);
+ Ptr<MgClassDefinitionCollection> classes = schema->GetClasses();
+ bFound = false;
+ for (INT32 i = 0; i < classes->GetCount(); i++)
+ {
+ Ptr<MgClassDefinition> klass = classes->GetItem(i);
+ if (klass->GetName() == L"Ext1")
+ {
+ bFound = true;
+ break;
+ }
+ }
+ CPPUNIT_ASSERT(bFound);
+
+ //1st variation of DescribeSchema() with the actual parent schema name
+ schemas = pService->DescribeSchema(lFeatureSource, L"SHP_Schema");
+ CPPUNIT_ASSERT(NULL != schemas.p);
+ CPPUNIT_ASSERT(1 == schemas->GetCount());
+ schema = schemas->GetItem(0);
+ classes = schema->GetClasses();
+ bFound = false;
+ for (INT32 i = 0; i < classes->GetCount(); i++)
+ {
+ Ptr<MgClassDefinition> klass = classes->GetItem(i);
+ if (klass->GetName() == L"Ext1")
+ {
+ bFound = true;
+ break;
+ }
+ }
+ CPPUNIT_ASSERT(bFound);
+ Ptr<MgStringCollection> findClassNames = new MgStringCollection();
+ findClassNames->Add(L"Ext1");
+
+ //2nd variation of DescribeSchema()
+ schemas = pService->DescribeSchema(lFeatureSource, L"SHP_Schema", findClassNames);
+ CPPUNIT_ASSERT(NULL != schemas.p);
+ CPPUNIT_ASSERT(1 == schemas->GetCount());
+ schema = schemas->GetItem(0);
+ classes = schema->GetClasses();
+ bFound = false;
+ for (INT32 i = 0; i < classes->GetCount(); i++)
+ {
+ Ptr<MgClassDefinition> klass = classes->GetItem(i);
+ if (klass->GetName() == L"Ext1")
+ {
+ bFound = true;
+ break;
+ }
+ }
+ CPPUNIT_ASSERT(bFound);
+
+ Ptr<MgClassDefinition> clsDef = pService->GetClassDefinition(lFeatureSource, L"SHP_Schema", L"Ext1");
+ CPPUNIT_ASSERT(NULL != clsDef.p);
+ }
+ catch(MgException* e)
+ {
+ STRING message = e->GetDetails(TEST_LOCALE);
+ STRING st = e->GetStackTrace(TEST_LOCALE);
+ message += L"\n" + st;
+ SAFE_RELEASE(e);
+ CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+ }
+ catch(FdoException* e)
+ {
+ STRING message = L"FdoException occurred: ";
+ message += e->GetExceptionMessage();
+ FDO_SAFE_RELEASE(e);
+ CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+ }
+ catch(...)
+ {
+ throw;
+ }
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
/// This test case exercises the FDO join optimization
///----------------------------------------------------------------------------
void TestFeatureService::TestCase_JoinFdoFeatures()
Modified: branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h 2012-07-05 13:16:54 UTC (rev 6852)
+++ branches/2.4/MgDev/Desktop/UnitTest/TestFeatureService.h 2012-07-05 15:27:56 UTC (rev 6853)
@@ -43,6 +43,7 @@
CPPUNIT_TEST(TestCase_SelectFeaturesTransformed);
CPPUNIT_TEST(TestCase_SelectScrollable);
CPPUNIT_TEST(TestCase_SelectAggregate);
+ CPPUNIT_TEST(TestCase_ExtendedFeatureClass);
CPPUNIT_TEST(TestCase_InsertFeatures);
CPPUNIT_TEST(TestCase_InsertFeaturesBatch);
CPPUNIT_TEST(TestCase_UpdateFeatures);
@@ -105,6 +106,7 @@
void TestCase_DeleteFeatures();
void TestCase_ExecuteSqlQuery();
void TestCase_ExecuteSqlNonQuery();
+ void TestCase_ExtendedFeatureClass();
void TestCase_GetSpatialContexts();
void TestCase_GetLongTransactions();
void TestCase_SetLongTransaction();
More information about the mapguide-commits
mailing list