[mapguide-commits] r7402 - in trunk/MgDev/Desktop: MgDesktop MgDesktop/Services MgDesktop/Services/Feature/Commands MgDesktop/System UnitTest

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Mar 20 09:05:17 PDT 2013


Author: jng
Date: 2013-03-20 09:05:16 -0700 (Wed, 20 Mar 2013)
New Revision: 7402

Modified:
   trunk/MgDev/Desktop/MgDesktop/Platform.ini
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h
   trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.h
   trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.cpp
   trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.h
   trunk/MgDev/Desktop/UnitTest/main.cpp
Log:
mg-desktop changes:
 - Port over #2214 fix
 - Port over GwsQueryEngine fallback support (#2213)
 - Suppress error dialogs from broken RDBMS FDO providers in the unit test runner. Such providers do not concern us as they are not exercised under any tests.

Modified: trunk/MgDev/Desktop/MgDesktop/Platform.ini
===================================================================
(Binary files differ)

Modified: trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp	2013-03-20 16:05:16 UTC (rev 7402)
@@ -424,16 +424,26 @@
 
     MG_FEATURE_SERVICE_TRY()
 
+#ifdef DEBUG_FDO_JOIN
+    FdoPtr<FdoIdentifierCollection> cmdPropNames = m_command->GetPropertyNames();
+    for (FdoInt32 i = 0; i < cmdPropNames->GetCount(); i++)
+    {
+        FdoPtr<FdoIdentifier> ident = cmdPropNames->GetItem(i);
+        STRING idStr = ident->ToString();
+        ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) [FdoISelect]: (%W)"), idStr.c_str()));
+    }
+#endif
+
     FdoPtr<FdoIFeatureReader> fdoReader = m_command->Execute();
     if (bForceOneToOne)
     {
         FdoPtr<FdoStringCollection> names = MgdFeatureUtil::MgToFdoStringCollection(idPropNames, false);
         FdoPtr<FdoIFeatureReader> forcedReader = new MgdFdoForcedOneToOneFeatureReader(fdoReader, names); 
-        ret = new MgdFeatureReader(m_connection, forcedReader);
+        ret = new MgdFeatureReader(m_connection, forcedReader, idPropNames);
     }
     else
     {
-        ret = new MgdFeatureReader(m_connection, fdoReader);
+        ret = new MgdFeatureReader(m_connection, fdoReader, idPropNames);
     }
     MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdSelectCommand.ExecuteJoined")
 

Modified: trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp	2013-03-20 16:05:16 UTC (rev 7402)
@@ -48,6 +48,7 @@
 
     // Set a default join query batch size
     m_nJoinQueryBatchSize = MgdConfigProperties::DefaultFeatureServicePropertyJoinQueryBatchSize;
+    m_bUseFdoJoinOptimization = MgdConfigProperties::DefaultFeatureServicePropertyUseFdoJoinOptimization; 
 
     MgConfiguration* config = MgConfiguration::GetInstance();
     if(config)
@@ -62,6 +63,11 @@
                             MgdConfigProperties::FeatureServicePropertyDataCacheSize,
                             m_nDataCacheSize,
                             MgdConfigProperties::DefaultFeatureServicePropertyDataCacheSize);
+        // Get FDO Join use flag 
+ 	    config->GetBoolValue(MgdConfigProperties::FeatureServicePropertiesSection, 
+                             MgdConfigProperties::FeatureServicePropertyUseFdoJoinOptimization, 
+                             m_bUseFdoJoinOptimization, 
+                             MgdConfigProperties::DefaultFeatureServicePropertyUseFdoJoinOptimization); 
     }
 }
 
@@ -183,7 +189,7 @@
 
             MgStringCollection arguments;
             arguments.Add(message);
-            throw new MgFeatureServiceException(L"MgServerSelectFeatures.SelectFeatures", __LINE__, __WFILE__, &arguments, L"", NULL);
+            throw new MgFeatureServiceException(L"MgdSelectFeatures.SelectFeatures", __LINE__, __WFILE__, &arguments, L"", NULL);
         }
 
         // Custom function specified using SelectAggregate,
@@ -323,7 +329,7 @@
         else
             reader = m_command->Execute();
 
-        CHECKNULL((MgReader*)reader, L"MgServerSelectFeatures.SelectFeatures");
+        CHECKNULL((MgReader*)reader, L"MgdSelectFeatures.SelectFeatures");
 
         if (executeSelectAggregate && m_customPropertyFound)
         {
@@ -340,7 +346,7 @@
         }
     }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerSelectFeatures.SelectFeatures")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgdSelectFeatures.SelectFeatures")
 
     return mgReader.Detach();
 }
@@ -348,7 +354,7 @@
 
 void MgdSelectFeatures::ApplyQueryOptions(bool isSelectAggregate)
 {
-    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyQueryOptions");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyQueryOptions");
 
     if (m_options != NULL)
     {
@@ -365,8 +371,8 @@
 // ClassProperties
 void MgdSelectFeatures::ApplyClassProperties()
 {
-    CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyClassProperties");
-    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyClassProperties");
+    CHECKNULL(m_options, L"MgdSelectFeatures.ApplyClassProperties");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyClassProperties");
 
     Ptr<MgStringCollection> properties = m_options->GetClassProperties();
 
@@ -381,25 +387,76 @@
     //secondary properties.
 
     FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
-    CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.ApplyClassProperties");
+    CHECKNULL((FdoIdentifierCollection*)fic, L"MgdSelectFeatures.ApplyClassProperties");
 
     for (INT32 i=0; i < cnt; i++)
     {
         STRING propertyName = properties->GetItem(i);
 
         FdoPtr<FdoIdentifier> fdoIden = FdoIdentifier::Create((FdoString*)propertyName.c_str());
-        CHECKNULL((FdoIdentifier*)fdoIden, L"MgServerSelectFeatures.ApplyClassProperties");
+        CHECKNULL((FdoIdentifier*)fdoIden, L"MgdSelectFeatures.ApplyClassProperties");
 
         fic->Add(fdoIden);
     }
 }
 
+void MgdSelectFeatures::ApplyClassPropertiesForFdoJoin(CREFSTRING primaryAlias, CREFSTRING secondaryAlias, CREFSTRING secondaryPrefix)
+{
+    CHECKNULL(m_options, L"MgdSelectFeatures.ApplyClassPropertiesForFdoJoin");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyClassPropertiesForFdoJoin");
 
+    Ptr<MgStringCollection> properties = m_options->GetClassProperties();
+
+    if (properties == NULL)
+        return; // Nothing to do
+
+    INT32 cnt = properties->GetCount();
+    if (cnt <= 0)
+        return; // Nothing to do
+
+    FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
+    CHECKNULL((FdoIdentifierCollection*)fic, L"MgdSelectFeatures.ApplyClassPropertiesForFdoJoin");
+
+    //If we're given an explicit property list, it will be whatever is presented by the Extended Feature Class
+    //So we have to "re-shape" this property list into a aliased qualified property list like the standard FDO
+    //join query. Basically, were doing a reverse property mapping.
+
+    for (INT32 i=0; i < cnt; i++)
+    {
+        STRING propertyName = properties->GetItem(i);
+
+        //Check if this name starts with prefix
+        //
+        // If it does, it's a secondary join property and should be re-aliased as [secondaryAlias].[propertyNameWithoutPrefix]
+        // Otherwise, it should be re-aliased as [primaryAlias].[propertyNameAsIs]
+        STRING reAliasedPropName;
+        if (propertyName.compare(0, secondaryPrefix.length(), secondaryPrefix) == 0)
+        {
+            reAliasedPropName = secondaryAlias;
+            reAliasedPropName += L".";
+            reAliasedPropName += propertyName.substr(secondaryPrefix.length());
+        }
+        else
+        {
+            reAliasedPropName = primaryAlias;
+            reAliasedPropName += L".";
+            reAliasedPropName += propertyName;
+        }
+
+        //This will now be [alias].[reAliasedPropertyName] AS [propertyName]
+        FdoPtr<FdoExpression> expr = FdoExpression::Parse((FdoString*)reAliasedPropName.c_str());
+        FdoPtr<FdoComputedIdentifier> fdoIden = FdoComputedIdentifier::Create((FdoString*)propertyName.c_str(), expr);
+        CHECKNULL((FdoComputedIdentifier*)fdoIden, L"MgdSelectFeatures.ApplyClassPropertiesForFdoJoin");
+
+        fic->Add(fdoIden);
+    }
+}
+
 // Computed properties
 void MgdSelectFeatures::ApplyComputedProperties()
 {
-    CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyComputedProperties");
-    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyComputedProperties");
+    CHECKNULL(m_options, L"MgdSelectFeatures.ApplyComputedProperties");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyComputedProperties");
 
     Ptr<MgStringPropertyCollection> properties = m_options->GetComputedProperties();
 
@@ -424,7 +481,7 @@
         if (str != NULL)
         {
             FdoPtr<FdoExpression> expression = FdoExpression::Parse(str);
-            CHECKNULL((FdoExpression*)expression, L"MgServerSelectFeatures.ApplyComputedProperties");
+            CHECKNULL((FdoExpression*)expression, L"MgdSelectFeatures.ApplyComputedProperties");
 
             bool udf = ContainsUdf(expression);
             if (!udf)
@@ -442,8 +499,8 @@
 //// Filter text
 //void MgdSelectFeatures::ApplyFilter()
 //{
-//    CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyFilter");
-//    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFilter");
+//    CHECKNULL(m_options, L"MgdSelectFeatures.ApplyFilter");
+//    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyFilter");
 //
 //    STRING filterText = m_options->GetFilter();
 //    if (filterText.empty()) { return; } // Nothing to do
@@ -454,7 +511,7 @@
 // Fetch size
 void MgdSelectFeatures::ApplyFetchSize()
 {
-    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFetchSize");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyFetchSize");
     if(m_options)
         m_command->SetFetchSize(m_options->GetFetchSize());
     else
@@ -464,8 +521,8 @@
 // Spatial Filter
 void MgdSelectFeatures::ApplyFilter()
 {
-    CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyFilter");
-    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFilter");
+    CHECKNULL(m_options, L"MgdSelectFeatures.ApplyFilter");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyFilter");
 
     FdoPtr<FdoFilter> regularFilter;
     FdoPtr<FdoSpatialCondition> spatialFilter;
@@ -477,7 +534,7 @@
     if (!filterText.empty())
     {
         regularFilter = FdoFilter::Parse(filterText.c_str());
-        #ifdef _DEBUG
+        #if defined(_DEBUG) || defined(DEBUG_FDO_JOIN)
         ACE_DEBUG((LM_ERROR, ACE_TEXT("FILTER(size=%d):\n%W\n\n"), filterText.length(), filterText.c_str()));
         #endif
     }
@@ -557,8 +614,8 @@
 // Ordering options
 void MgdSelectFeatures::ApplyOrderingOptions()
 {
-    CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyOrderingOptions");
-    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyOrderingOptions");
+    CHECKNULL(m_options, L"MgdSelectFeatures.ApplyOrderingOptions");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyOrderingOptions");
 
     Ptr<MgStringCollection> properties = m_options->GetOrderingProperties();
 
@@ -576,11 +633,11 @@
 
         MgStringCollection arguments;
         arguments.Add(message);
-        throw new MgFeatureServiceException(L"MgServerSelectFeatures.ApplyOrderingOptions", __LINE__, __WFILE__, &arguments, L"", NULL);
+        throw new MgFeatureServiceException(L"MgdSelectFeatures.ApplyOrderingOptions", __LINE__, __WFILE__, &arguments, L"", NULL);
     }
 
     FdoPtr<FdoIdentifierCollection> fic = m_command->GetOrdering();
-    CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.ApplyOrderingOptions");
+    CHECKNULL((FdoIdentifierCollection*)fic, L"MgdSelectFeatures.ApplyOrderingOptions");
 
     // Order option Asc or Desc (default is Asc)
     FdoOrderingOption option = MgdFeatureUtil::GetFdoOrderingOption(m_options->GetOrderOption());
@@ -593,7 +650,7 @@
         if (!propertyName.empty())
         {
             FdoPtr<FdoIdentifier> fdoIden = FdoIdentifier::Create((FdoString*)propertyName.c_str());
-            CHECKNULL((FdoIdentifier*)fdoIden, L"MgServerSelectFeatures.ApplyOrderingOptions");
+            CHECKNULL((FdoIdentifier*)fdoIden, L"MgdSelectFeatures.ApplyOrderingOptions");
 
             fic->Add(fdoIden);
         }
@@ -647,13 +704,13 @@
 void MgdSelectFeatures::AddFdoComputedProperty(CREFSTRING aliasName, FdoExpression* expression)
 {
     FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
-    CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.AddFdoComputedProperty");
+    CHECKNULL((FdoIdentifierCollection*)fic, L"MgdSelectFeatures.AddFdoComputedProperty");
 
     FdoString* expName = aliasName.c_str();
     if (expName != NULL)
     {
         FdoPtr<FdoComputedIdentifier> fdoIden = FdoComputedIdentifier::Create(expName, expression);
-        CHECKNULL((FdoComputedIdentifier*)fdoIden, L"MgServerSelectFeatures.AddFdoComputedProperty");
+        CHECKNULL((FdoComputedIdentifier*)fdoIden, L"MgdSelectFeatures.AddFdoComputedProperty");
 
         fic->Add(fdoIden);
     }
@@ -661,10 +718,10 @@
 
 void MgdSelectFeatures::AddCustomComputedProperty(CREFSTRING aliasName, FdoExpression* expression)
 {
-    CHECKNULL((FdoExpression*)expression, L"MgServerSelectFeatures.AddCustomComputedProperty");
+    CHECKNULL((FdoExpression*)expression, L"MgdSelectFeatures.AddCustomComputedProperty");
 
     FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
-    CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.AddCustomComputedProperty");
+    CHECKNULL((FdoIdentifierCollection*)fic, L"MgdSelectFeatures.AddCustomComputedProperty");
 
     // If property is already found, two custom properties are not supported and therefore throw exception
     if (m_customPropertyFound)
@@ -673,7 +730,7 @@
 
         MgStringCollection arguments;
         arguments.Add(message);
-        throw new MgFeatureServiceException(L"MgServerSelectFeatures.AddCustomComputedProperty", __LINE__, __WFILE__, &arguments, L"", NULL);
+        throw new MgFeatureServiceException(L"MgdSelectFeatures.AddCustomComputedProperty", __LINE__, __WFILE__, &arguments, L"", NULL);
     }
 
     // Downcast to FdoFunction
@@ -731,7 +788,7 @@
 
                 MgStringCollection arguments;
                 arguments.Add(message);
-                throw new MgFeatureServiceException(L"MgServerSelectFeatures.ValidateConstraintsOnCustomFunctions",
+                throw new MgFeatureServiceException(L"MgdSelectFeatures.ValidateConstraintsOnCustomFunctions",
                     __LINE__, __WFILE__, &arguments, L"", NULL);
             }
             MgdFeatureUtil::ValidateCustomConstraints(m_customFunction);
@@ -750,7 +807,7 @@
     {
         m_command = MgdFeatureServiceCommand::CreateCommand(resource, FdoCommandType_SelectAggregates);
     }
-    CHECKNULL((MgdFeatureServiceCommand*)m_command, L"MgServerSelectFeatures.CreateCommand");
+    CHECKNULL((MgdFeatureServiceCommand*)m_command, L"MgdSelectFeatures.CreateCommand");
 }
 
 void MgdSelectFeatures::ValidateParam(MgResourceIdentifier* resource, CREFSTRING className)
@@ -811,8 +868,8 @@
 
 void MgdSelectFeatures::ApplyFdoGroupingProperties(MgStringCollection* propertyNames)
 {
-    CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyFdoGroupingProperties");
-    CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFdoGroupingProperties");
+    CHECKNULL(m_options, L"MgdSelectFeatures.ApplyFdoGroupingProperties");
+    CHECKNULL(m_command, L"MgdSelectFeatures.ApplyFdoGroupingProperties");
 
     Ptr<MgStringCollection> properties = SAFE_ADDREF(propertyNames);
 
@@ -830,18 +887,18 @@
 
         MgStringCollection arguments;
         arguments.Add(message);
-        throw new MgFeatureServiceException(L"MgServerSelectFeatures.ApplyFdoGroupingProperties", __LINE__, __WFILE__, &arguments, L"", NULL);
+        throw new MgFeatureServiceException(L"MgdSelectFeatures.ApplyFdoGroupingProperties", __LINE__, __WFILE__, &arguments, L"", NULL);
     }
 
     FdoPtr<FdoIdentifierCollection> fic = ((MgdFeatureServiceCommand*)m_command)->GetGrouping();
-    CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.ApplyFdoGroupingProperties");
+    CHECKNULL((FdoIdentifierCollection*)fic, L"MgdSelectFeatures.ApplyFdoGroupingProperties");
 
     for (INT32 i=0; i < cnt; i++)
     {
         STRING propertyName = properties->GetItem(i);
 
         FdoPtr<FdoIdentifier> fdoIden = FdoIdentifier::Create((FdoString*)propertyName.c_str());
-        CHECKNULL((FdoIdentifier*)fdoIden, L"MgServerSelectFeatures.ApplyFdoGroupingProperties");
+        CHECKNULL((FdoIdentifier*)fdoIden, L"MgdSelectFeatures.ApplyFdoGroupingProperties");
 
         fic->Add(fdoIden);
     }
@@ -873,7 +930,7 @@
         if (str != NULL)
         {
             FdoPtr<FdoExpression> expression = FdoExpression::Parse(str);
-            CHECKNULL((FdoExpression*)expression, L"MgServerSelectFeatures.ContainsCustomFunction");
+            CHECKNULL((FdoExpression*)expression, L"MgdSelectFeatures.ContainsCustomFunction");
 
             hasCustomFunction = ContainsUdf(expression);
         }
@@ -886,7 +943,7 @@
 
         MgStringCollection arguments;
         arguments.Add(message);
-        throw new MgFeatureServiceException(L"MgServerSelectFeatures.ContainsCustomFunction",
+        throw new MgFeatureServiceException(L"MgdSelectFeatures.ContainsCustomFunction",
             __LINE__, __WFILE__, &arguments, L"", NULL);
     }
 
@@ -913,15 +970,15 @@
 {
     bool bCalculationExists = false;
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.FindFeatureCalculation");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.FindFeatureCalculation");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.FindFeatureCalculation");
+    CHECKNULL(extensions, L"MgdSelectFeatures.FindFeatureCalculation");
 
     for (int i = 0; i < extensions->GetCount(); i++)
     {
         MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgServerSelectFeatures.FindFeatureCalculation");
+        CHECKNULL(extension, L"MgdSelectFeatures.FindFeatureCalculation");
         STRING name = (STRING)extension->GetName();
 
         STRING parsedSchemaName, parsedExtensionName;
@@ -948,15 +1005,15 @@
 {
     bool bJoinPropertiesExists = false;
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.FindFeatureJoinProperties");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.FindFeatureJoinProperties");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.FindFeatureJoinProperties");
+    CHECKNULL(extensions, L"MgdSelectFeatures.FindFeatureJoinProperties");
 
     for (int i = 0; i < extensions->GetCount(); i++)
     {
         MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgServerSelectFeatures.FindFeatureJoinProperties");
+        CHECKNULL(extension, L"MgdSelectFeatures.FindFeatureJoinProperties");
         STRING name = (STRING)extension->GetName();
 
         STRING parsedSchemaName, parsedExtensionName;
@@ -981,15 +1038,15 @@
 {
     MG_FEATURE_SERVICE_TRY()
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.UpdateCommandOnJoinCalculation");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation");
+    CHECKNULL(extensions, L"MgdSelectFeatures.UpdateCommandOnJoinCalculation");
 
     for (int i = 0; i < extensions->GetCount(); i++)
     {
         MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation");
+        CHECKNULL(extension, L"MgdSelectFeatures.UpdateCommandOnJoinCalculation");
         STRING name = (STRING)extension->GetName();
 
         STRING parsedSchemaName, parsedExtensionName;
@@ -1042,22 +1099,22 @@
             break;
         }
     }
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgdSelectFeatures.UpdateCommandOnJoinCalculation")
 }
 
 void MgdSelectFeatures::UpdateCommandOnCalculation(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName)
 {
     MG_FEATURE_SERVICE_TRY()
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.UpdateCommandOnCalculation");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.UpdateCommandOnCalculation");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.UpdateCommandOnCalculation");
+    CHECKNULL(extensions, L"MgdSelectFeatures.UpdateCommandOnCalculation");
 
     for (int i = 0; i < extensions->GetCount(); i++)
     {
         MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgServerSelectFeatures.UpdateCommandOnCalculation");
+        CHECKNULL(extension, L"MgdSelectFeatures.UpdateCommandOnCalculation");
         STRING name = (STRING)extension->GetName();
 
         STRING parsedSchemaName, parsedExtensionName;
@@ -1177,7 +1234,7 @@
             break;
         }
     }
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgServerSelectFeatures.UpdateCommandOnCalculation")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgdSelectFeatures.UpdateCommandOnCalculation")
 }
 
 MgdGwsFeatureReader* MgdSelectFeatures::JoinFeatures(MgResourceIdentifier* featureSourceIdentifier, CREFSTRING extensionName, FdoFilter* filter)
@@ -1189,15 +1246,15 @@
     FdoPtr<IGWSQueryDefinition> qd;
     FdoPtr<MgdGwsConnectionPool> pool = MgdGwsConnectionPool::Create();
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.JoinFeatures");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.JoinFeatures");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.JoinFeatures");
+    CHECKNULL(extensions, L"MgdSelectFeatures.JoinFeatures");
 
     for (int i = 0; i < extensions->GetCount(); i++)
     {
         MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgServerSelectFeatures.JoinFeatures");
+        CHECKNULL(extension, L"MgdSelectFeatures.JoinFeatures");
         STRING name = (STRING)extension->GetName();
 
         STRING parsedSchemaName, parsedExtensionName;
@@ -1219,7 +1276,7 @@
             }
             else
             {
-                throw new MgdConnectionFailedException(L"MgServerSelectFeatures.JoinFeatures",
+                throw new MgdConnectionFailedException(L"MgdSelectFeatures.JoinFeatures",
                     __LINE__, __WFILE__, NULL, L"", NULL);
             }
 
@@ -1306,13 +1363,13 @@
                 lsellist,
                 GWSQualifiedName(primaryConnectionName.c_str(), primaryFsSchema.c_str(), primaryFsClassName.c_str()),
                 lfilter);
-            CHECKNULL(lqd, L"MgServerSelectFeatures.JoinFeatures");
+            CHECKNULL(lqd, L"MgdSelectFeatures.JoinFeatures");
             qd = lqd;
 
             IGWSJoinQueryDefinition* jqd = NULL;
 
             MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
-            CHECKNULL(attributeRelates, L"MgServerSelectFeatures.JoinFeatures");
+            CHECKNULL(attributeRelates, L"MgdSelectFeatures.JoinFeatures");
 
             bool bForceOneToOne = true;
             Ptr<MgStringCollection> attributeNameDelimiters = new MgStringCollection();
@@ -1325,7 +1382,7 @@
             for (int attributeRelateIndex = 0; attributeRelateIndex < attributeRelates->GetCount(); attributeRelateIndex++)
             {
                 MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(attributeRelateIndex);
-                CHECKNULL(attributeRelate, L"MgServerSelectFeatures.JoinFeatures");
+                CHECKNULL(attributeRelate, L"MgdSelectFeatures.JoinFeatures");
 
                 // Get the secondary resource id
                 STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
@@ -1366,7 +1423,7 @@
                     }
                     else
                     {
-                        throw new MgdConnectionFailedException(L"MgServerSelectFeatures.JoinFeatures",
+                        throw new MgdConnectionFailedException(L"MgdSelectFeatures.JoinFeatures",
                             __LINE__, __WFILE__, NULL, L"", NULL);
                     }
                 }
@@ -1386,7 +1443,7 @@
                     rsellist,
                     GWSQualifiedName(secondaryConnectionName.c_str(), secondaryFsSchema.c_str(), secondaryFsClassName.c_str()),
                     rfilter);
-                CHECKNULL(rqd, L"MgServerSelectFeatures.JoinFeatures");
+                CHECKNULL(rqd, L"MgdSelectFeatures.JoinFeatures");
 
                 // Get Join Attributes
                 FdoPtr<FdoStringCollection> lattrs = FdoStringCollection::Create();
@@ -1394,14 +1451,14 @@
 
                 // Determine the number of RelateProperties (attributes)
                 MdfModel::RelatePropertyCollection* relateProperties = attributeRelate->GetRelateProperties();
-                CHECKNULL(relateProperties, L"MgServerSelectFeatures.JoinFeatures");
+                CHECKNULL(relateProperties, L"MgdSelectFeatures.JoinFeatures");
                 int nRelatePropertyCount = relateProperties->GetCount();
 
                 // For each RelateProperty need to do the following
                 for (int relatePropertyIndex = 0; relatePropertyIndex < nRelatePropertyCount; relatePropertyIndex++)
                 {
                     MdfModel::RelateProperty* relateProperty = relateProperties->GetAt(relatePropertyIndex);
-                    CHECKNULL(relateProperty, L"MgServerSelectFeatures.JoinFeatures");
+                    CHECKNULL(relateProperty, L"MgdSelectFeatures.JoinFeatures");
 
                     // Get the FeatureClassProperty (primary attribute)
                     STRING primaryAttribute = (STRING)relateProperty->GetFeatureClassProperty();
@@ -1482,7 +1539,7 @@
         }
     }
 
-    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceIdentifier, L"MgServerSelectFeatures.JoinFeatures")
+    MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceIdentifier, L"MgdSelectFeatures.JoinFeatures")
 
     // Now that the reader has been created we will need to mark all of the connections it uses as OwnReader() because the GWS reader will be
     // taking ownership of the connections. We have to do it this late in the code in case an exception is thrown somewhere before this.
@@ -1494,7 +1551,7 @@
 
 void MgdSelectFeatures::ParseQualifiedClassNameForCalculation(MdfModel::Extension* extension, CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className)
 {
-    CHECKNULL(extension, L"MgServerSelectFeatures.ParseQualifiedClassNameForCalculation");
+    CHECKNULL(extension, L"MgdSelectFeatures.ParseQualifiedClassNameForCalculation");
 
     MgUtil::ParseQualifiedClassName(qualifiedClassName, schemaName, className);
 
@@ -1510,15 +1567,15 @@
 {
     Ptr<MgResourceIdentifier> secResId;
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.GetSecondaryResourceIdentifier");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+    CHECKNULL(extensions, L"MgdSelectFeatures.GetSecondaryResourceIdentifier");
 
     for (int i = 0; i < extensions->GetCount(); i++)
     {
         MdfModel::Extension* extension = extensions->GetAt(i);
-        CHECKNULL(extension, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+        CHECKNULL(extension, L"MgdSelectFeatures.GetSecondaryResourceIdentifier");
 
         // Get the extension name
         STRING name = (STRING)extension->GetName();
@@ -1534,7 +1591,7 @@
         {
             // Determine the number of secondary sources (AttributeRelates)
             MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
-            CHECKNULL(attributeRelates, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+            CHECKNULL(attributeRelates, L"MgdSelectFeatures.GetSecondaryResourceIdentifier");
             int nAttributeRelateCount = attributeRelates->GetCount();
 
             // Find the specified relation name
@@ -1542,7 +1599,7 @@
                 for (int attributeRelateIndex = 0; attributeRelateIndex < nAttributeRelateCount; attributeRelateIndex++)
                 {
                     MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(attributeRelateIndex);
-                    CHECKNULL(attributeRelate, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+                    CHECKNULL(attributeRelate, L"MgdSelectFeatures.GetSecondaryResourceIdentifier");
 
                     // Get the name for the join relationship
                     STRING attributeRelateName = (STRING)attributeRelate->GetName();
@@ -1570,6 +1627,10 @@
 {
     bool bSupported = false;
 
+    //If disabled on a global level, don't even bother continuing 
+    if (!m_bUseFdoJoinOptimization)
+        return false;
+
     MG_FEATURE_SERVICE_TRY()
 
     //This could be qualified, so parse it to be sure
@@ -1577,10 +1638,10 @@
     STRING extName;
     MgUtil::ParseQualifiedClassName(extensionName, schemaName, extName);
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.SupportsFdoJoin");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.SupportsFdoJoin");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.SupportsFdoJoin");
+    CHECKNULL(extensions, L"MgdSelectFeatures.SupportsFdoJoin");
 
     MdfModel::Extension* extension = NULL;
     for (INT32 i = 0; i < extensions->GetCount(); i++) 
@@ -1605,7 +1666,7 @@
     {
         if (!conn->IsConnectionOpen())
         {
-            throw new MgdConnectionFailedException(L"MgServerSelectFeatures.SupportsFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgdConnectionFailedException(L"MgdSelectFeatures.SupportsFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
         FdoPtr<FdoIConnection> fdoConn = conn->GetConnection();
@@ -1751,7 +1812,7 @@
         bSupported = true;
     }
 
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerSelectFeatures.SupportsFdoJoin")
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdSelectFeatures.SupportsFdoJoin")
 
     return bSupported;
 }
@@ -1763,7 +1824,7 @@
         return true; //Inconsequential
 
     FdoPtr<FdoIDescribeSchema> descSchema = dynamic_cast<FdoIDescribeSchema*>(fdoConn->CreateCommand(FdoCommandType_DescribeSchema));
-    CHECKNULL((FdoIDescribeSchema*)descSchema, L"MgServerSelectFeatures.SelectFdoJoin");
+    CHECKNULL((FdoIDescribeSchema*)descSchema, L"MgdSelectFeatures.SelectFdoJoin");
 
     if (!schemaName.empty())
     {
@@ -1799,7 +1860,7 @@
     if (NULL == (FdoClassDefinition*)classDef)
     {
         //TODO: Refine message if available
-        throw new MgClassNotFoundException(L"MgServerSelectFeatures.IsFunctionOnPrimaryProperty", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgClassNotFoundException(L"MgdSelectFeatures.IsFunctionOnPrimaryProperty", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     FdoPtr<FdoPropertyDefinitionCollection> properties = classDef->GetProperties();
@@ -1831,13 +1892,13 @@
     {
         if (!conn->IsConnectionOpen())
         {
-            throw new MgdConnectionFailedException(L"MgServerSelectFeatures.SupportsFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgdConnectionFailedException(L"MgdSelectFeatures.SupportsFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
         FdoPtr<FdoIConnection> fdoConn = conn->GetConnection();
 
         FdoPtr<FdoIDescribeSchema> descSchema = dynamic_cast<FdoIDescribeSchema*>(fdoConn->CreateCommand(FdoCommandType_DescribeSchema));
-        CHECKNULL((FdoIDescribeSchema*)descSchema, L"MgServerSelectFeatures.SelectFdoJoin");
+        CHECKNULL((FdoIDescribeSchema*)descSchema, L"MgdSelectFeatures.SelectFdoJoin");
 
         if (!secondarySchema.empty())
         {
@@ -1873,7 +1934,7 @@
         if (NULL == (FdoClassDefinition*)classDef)
         {
             //TODO: Refine message if available
-            throw new MgClassNotFoundException(L"MgServerSelectFeatures.FilterContainsSecondaryProperties", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgClassNotFoundException(L"MgdSelectFeatures.FilterContainsSecondaryProperties", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
         FdoPtr<FdoPropertyDefinitionCollection> propDefs = classDef->GetProperties();
@@ -1904,10 +1965,10 @@
     STRING extName;
     MgUtil::ParseQualifiedClassName(extensionName, schemaName, extName);
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.SelectFdoJoin");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.SelectFdoJoin");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.SelectFdoJoin");
+    CHECKNULL(extensions, L"MgdSelectFeatures.SelectFdoJoin");
 
     MdfModel::Extension* extension = NULL;
     for (INT32 i = 0; i < extensions->GetCount(); i++) 
@@ -1920,10 +1981,14 @@
         }
     }
 
-    CHECKNULL(extension, L"MgServerSelectFeatures.SelectFdoJoin");
-    m_command->SetFeatureClassName(extension->GetFeatureClass().c_str());
+    CHECKNULL(extension, L"MgdSelectFeatures.SelectFdoJoin");
+    FdoString* clsName = extension->GetFeatureClass().c_str();
+    m_command->SetFeatureClassName(clsName);
+#ifdef DEBUG_FDO_JOIN
+    ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FdoISelect] Set primary feature class: %W"), clsName));
+#endif
     MdfModel::AttributeRelateCollection* relates = extension->GetAttributeRelates();
-    CHECKNULL(relates, L"MgServerSelectFeatures.SelectFdoJoin");
+    CHECKNULL(relates, L"MgdSelectFeatures.SelectFdoJoin");
     MdfModel::AttributeRelate* relate = relates->GetAt(0);
 
     const MdfModel::MdfString& prefix = relate->GetName();
@@ -1950,20 +2015,18 @@
     {
         if (!conn->IsConnectionOpen())
         {
-            throw new MgdConnectionFailedException(L"MgServerSelectFeatures.SelectFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
+            throw new MgdConnectionFailedException(L"MgdSelectFeatures.SelectFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
-        CHECKNULL(m_command, L"MgServerSelectFeatures.SelectFdoJoin");
+        CHECKNULL(m_command, L"MgdSelectFeatures.SelectFdoJoin");
         FdoPtr<FdoIConnection> fdoConn = conn->GetConnection();
 
         bool bAppliedProperties = false;
         if (m_options != NULL)
         {
-            //ApplyClassProperties();
             ApplyComputedProperties();
             // TODO: We need to find out if there are any filters involving the secondary side
             ApplyFilter();
-            // ApplySpatialFilter();
             ApplyOrderingOptions();
             // We don't apply aggregate options here because these go through the FDO Expression Engine
             ApplyAggregateOptions(isAggregate);
@@ -1974,7 +2037,7 @@
             Ptr<MgStringCollection> props = m_options->GetClassProperties();
             if (props->GetCount() > 0)
             {
-                ApplyClassProperties();
+                ApplyClassPropertiesForFdoJoin(primaryAlias, secondaryAlias, prefix);
                 bAppliedProperties = true;
             }
         }
@@ -2056,7 +2119,7 @@
     else
         ret = ((MgdSelectCommand*)m_command.p)->ExecuteJoined(idPropNames, bForceOneToOne);
 
-    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerSelectFeatures.SelectFdoJoin")
+    MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdSelectFeatures.SelectFdoJoin")
 
     return ret.Detach();
 }
@@ -2072,10 +2135,10 @@
     STRING extName;
     MgUtil::ParseQualifiedClassName(extensionName, schemaName, extName);
 
-    CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.SupportsFdoJoin");
+    CHECKNULL(m_featureSourceCacheItem.p, L"MgdSelectFeatures.SupportsFdoJoin");
     MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
     MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
-    CHECKNULL(extensions, L"MgServerSelectFeatures.SupportsFdoJoin");
+    CHECKNULL(extensions, L"MgdSelectFeatures.SupportsFdoJoin");
 
     MdfModel::Extension* extension = NULL;
     for (INT32 i = 0; i < extensions->GetCount(); i++) 
@@ -2088,10 +2151,10 @@
         }
     }
 
-    CHECKNULL(extension, L"MgServerSelectFeatures.SelectFdoJoin");
+    CHECKNULL(extension, L"MgdSelectFeatures.SelectFdoJoin");
     m_command->SetFeatureClassName(extension->GetFeatureClass().c_str());
     MdfModel::AttributeRelateCollection* relates = extension->GetAttributeRelates();
-    CHECKNULL(relates, L"MgServerSelectFeatures.SelectFdoJoin");
+    CHECKNULL(relates, L"MgdSelectFeatures.SelectFdoJoin");
     MdfModel::AttributeRelate* relate = relates->GetAt(0);
 
     const MdfModel::MdfString& prefix = relate->GetName();
@@ -2156,7 +2219,7 @@
 void MgdSelectFeatures::ApplyClassProperties(FdoIConnection* fdoConn, CREFSTRING schemaName, CREFSTRING className, MgStringCollection* idPropNames, CREFSTRING alias, CREFSTRING prefix)
 {
     FdoPtr<FdoIDescribeSchema> descSchema = dynamic_cast<FdoIDescribeSchema*>(fdoConn->CreateCommand(FdoCommandType_DescribeSchema));
-    CHECKNULL((FdoIDescribeSchema*)descSchema, L"MgServerSelectFeatures.SelectFdoJoin");
+    CHECKNULL((FdoIDescribeSchema*)descSchema, L"MgdSelectFeatures.SelectFdoJoin");
 
     if (!schemaName.empty())
     {
@@ -2192,7 +2255,7 @@
     if (NULL == (FdoClassDefinition*)classDef)
     {
         //TODO: Refine message if available
-        throw new MgClassNotFoundException(L"MgServerSelectFeatures.ApplyClassProperties", __LINE__, __WFILE__, NULL, L"", NULL);
+        throw new MgClassNotFoundException(L"MgdSelectFeatures.ApplyClassProperties", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     FdoPtr<FdoIdentifierCollection> propNames = m_command->GetPropertyNames();

Modified: trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h	2013-03-20 16:05:16 UTC (rev 7402)
@@ -95,8 +95,12 @@
     INT32 m_nJoinQueryBatchSize;
 
     INT32 m_nDataCacheSize;
+    // This is the overriding flag that decides if we should test for and use the FDO Join 
+    // APIs if possible 
+    bool m_bUseFdoJoinOptimization; 
 
     // FDO join optimization
+    void ApplyClassPropertiesForFdoJoin(CREFSTRING primaryAlias, CREFSTRING secondaryAlias, CREFSTRING secondaryPrefix); 
     bool IsFunctionOnPrimaryProperty(FdoFunction* function, FdoIConnection* conn, CREFSTRING schemaName, CREFSTRING className);
     bool SupportsFdoJoin(MgResourceIdentifier* featureSourceId, CREFSTRING extension, bool isAggregate);
     MgReader* SelectFdoJoin(MgResourceIdentifier* featureSourceId, CREFSTRING extension, bool isAggregate);

Modified: trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.cpp	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.cpp	2013-03-20 16:05:16 UTC (rev 7402)
@@ -6,10 +6,11 @@
 #include "Services/Feature/FdoConnectionUtil.h"
 #include "Fdo.h"
 
-MgdFeatureReader::MgdFeatureReader(MgdFeatureConnection* conn, FdoIFeatureReader* reader)
+MgdFeatureReader::MgdFeatureReader(MgdFeatureConnection* conn, FdoIFeatureReader* reader, MgStringCollection* forceIdProps)
 {
 	m_reader = FDO_SAFE_ADDREF(reader);
     m_connection = SAFE_ADDREF(conn);
+    m_forceIdProps = SAFE_ADDREF(forceIdProps); //This is only passed in for select queries that involve the FDO Join APIs
 
     // The reader takes ownership of the FDO connection
     m_connection->OwnReader();
@@ -730,6 +731,39 @@
         // Convert FdoClassDefinition to MgClassDefinition
         m_classDef = MgdFeatureUtil::GetMgClassDefinition(fdoClassDefinition, true);
         CHECKNULL(m_classDef.p, L"MgdFeatureReader::GetClassDefinition");
+
+        // The class definition presented by a FDO reader from a join select query will probably
+        // not contain any identity properties, thereby violating our golden rule of selection (no id props = unselectable)
+        // so for such queries executed by MapGuide, we pass this list of identity properties on to this reader (sourced
+        // with the identity properties from the "primary" class definition) so that we can "rewrite" the converted MgClassDefinition
+        if (NULL != m_forceIdProps && m_forceIdProps->GetCount() > 0)
+        {
+            Ptr<MgPropertyDefinitionCollection> clsProps = m_classDef->GetProperties();
+            Ptr<MgPropertyDefinitionCollection> clsIdProps = m_classDef->GetIdentityProperties();
+
+            // This is most likely empty, but we're overwriting this anyway, so clear it
+            clsIdProps->Clear();
+
+            // Copy across any properties from the explicity identity property name list
+            for (INT32 i = 0; i < m_forceIdProps->GetCount(); i++)
+            {
+                STRING propName = m_forceIdProps->GetItem(i);
+                INT32 pidx = clsProps->IndexOf(propName);
+                if (pidx >= 0)
+                {
+                    Ptr<MgPropertyDefinition> p = clsProps->GetItem(pidx);
+                    clsIdProps->Add(p);
+                } //else should we care about correctness?
+            }
+        }
+
+#ifdef DEBUG_FDO_JOIN
+        Ptr<MgPropertyDefinitionCollection> idProps = m_classDef->GetIdentityProperties();
+        Ptr<MgPropertyDefinitionCollection> props = m_classDef->GetProperties();
+        INT32 idCount = idProps->GetCount();
+        INT32 propCount = props->GetCount();
+        ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) [MgFeatureReader::GetClassDefinition] %d props, %d identity props"), propCount, idCount));
+#endif
     }
 
     MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureReader::GetClassDefinition")
@@ -754,6 +788,39 @@
         // Convert FdoClassDefinition to MgClassDefinition
         m_classDef = MgdFeatureUtil::GetMgClassDefinition(fdoClassDefinition, false);
         CHECKNULL(m_classDef.p, L"MgdFeatureReader::GetClassDefinitionNoXml");
+
+        // The class definition presented by a FDO reader from a join select query will probably
+        // not contain any identity properties, thereby violating our golden rule of selection (no id props = unselectable)
+        // so for such queries executed by MapGuide, we pass this list of identity properties on to this reader (sourced
+        // with the identity properties from the "primary" class definition) so that we can "rewrite" the converted MgClassDefinition
+        if (NULL != m_forceIdProps && m_forceIdProps->GetCount() > 0)
+        {
+            Ptr<MgPropertyDefinitionCollection> clsProps = m_classDef->GetProperties();
+            Ptr<MgPropertyDefinitionCollection> clsIdProps = m_classDef->GetIdentityProperties();
+
+            // This is most likely empty, but we're overwriting this anyway, so clear it
+            clsIdProps->Clear();
+
+            // Copy across any properties from the explicity identity property name list
+            for (INT32 i = 0; i < m_forceIdProps->GetCount(); i++)
+            {
+                STRING propName = m_forceIdProps->GetItem(i);
+                INT32 pidx = clsProps->IndexOf(propName);
+                if (pidx >= 0)
+                {
+                    Ptr<MgPropertyDefinition> p = clsProps->GetItem(pidx);
+                    clsIdProps->Add(p);
+                } //else should we care about correctness?
+            }
+        }
+
+#ifdef DEBUG_FDO_JOIN
+        Ptr<MgPropertyDefinitionCollection> idProps = m_classDef->GetIdentityProperties();
+        Ptr<MgPropertyDefinitionCollection> props = m_classDef->GetProperties();
+        INT32 idCount = idProps->GetCount();
+        INT32 propCount = props->GetCount();
+        ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) [MgFeatureReader::GetClassDefinition] %d props, %d identity props"), propCount, idCount));
+#endif
     }
 
     MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgdFeatureReader::GetClassDefinitionNoXml")

Modified: trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.h
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.h	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/MgDesktop/Services/FeatureReader.h	2013-03-20 16:05:16 UTC (rev 7402)
@@ -13,7 +13,7 @@
 class MG_DESKTOP_API MgdFeatureReader : public MgFeatureReader
 {
 INTERNAL_API:
-	MgdFeatureReader(MgdFeatureConnection* conn, FdoIFeatureReader* reader);
+	MgdFeatureReader(MgdFeatureConnection* conn, FdoIFeatureReader* reader, MgStringCollection* forceIdProps = NULL);
 
 EXTERNAL_API:
 	virtual ~MgdFeatureReader();
@@ -206,6 +206,7 @@
 	FdoIFeatureReader* m_reader;
     Ptr<MgClassDefinition> m_classDef;
     Ptr<MgdFeatureConnection> m_connection;
+    Ptr<MgStringCollection> m_forceIdProps;
 };
 /// \}
 #endif
\ No newline at end of file

Modified: trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.cpp	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.cpp	2013-03-20 16:05:16 UTC (rev 7402)
@@ -185,6 +185,8 @@
 const INT32  MgdConfigProperties::DefaultFeatureServicePropertyDataTransactionTimerInterval  = 60;
 const STRING MgdConfigProperties::FeatureServicePropertyFDOConnectionTimeoutCustom           = L"FDOConnectionTimeoutCustom";
 const STRING MgdConfigProperties::DefaultFeatureServicePropertyFDOConnectionTimeoutCustom    = L"OSGeo.WMS:120";
+const STRING MgdConfigProperties::FeatureServicePropertyUseFdoJoinOptimization               = L"UseFdoJoinOptimization";
+const bool   MgdConfigProperties::DefaultFeatureServicePropertyUseFdoJoinOptimization        = true;
 
 // ******************************************************************
 // Mapping Service Properties

Modified: trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.h
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.h	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/MgDesktop/System/ConfigProperties.h	2013-03-20 16:05:16 UTC (rev 7402)
@@ -167,6 +167,10 @@
     static const STRING FeatureServicePropertyFDOConnectionTimeoutCustom;        /// value("FDOConnectionTimeoutCustom")
     static const STRING DefaultFeatureServicePropertyFDOConnectionTimeoutCustom; /// value("OSGeo.WMS:120")
 
+    /// Defines whether to use the FDO Join APIs for Feature Joins where applicable and supported
+    static const STRING FeatureServicePropertyUseFdoJoinOptimization;            /// value("UseFdoJoinOptimization")
+    static const bool DefaultFeatureServicePropertyUseFdoJoinOptimization;       /// value(true)
+
     /// MAPPING SERVICE PROPERTIES SECTION -------------------------------------------------------------------------------
 
     /// Mapping Service properties

Modified: trunk/MgDev/Desktop/UnitTest/main.cpp
===================================================================
--- trunk/MgDev/Desktop/UnitTest/main.cpp	2013-03-20 01:55:18 UTC (rev 7401)
+++ trunk/MgDev/Desktop/UnitTest/main.cpp	2013-03-20 16:05:16 UTC (rev 7402)
@@ -51,6 +51,9 @@
     ACE_DEBUG((LM_INFO, ACE_TEXT("Initialize Platform.ini\n")));
     //Benchmark this
 #ifdef WIN32
+    //Muffle errors due to broken FDO RDBMS provider dlls, they aren't the ones exercised
+    //under test anyway
+    SetErrorMode(SEM_FAILCRITICALERRORS);
     long lStart = GetTickCount();
 #endif
     MgdPlatform::Initialize(L"Platform.ini");



More information about the mapguide-commits mailing list