[mapguide-commits] r4435 - trunk/MgDev/Server/src/Services/Feature
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Mon Dec 14 02:59:28 EST 2009
Author: leaf
Date: 2009-12-14 02:59:27 -0500 (Mon, 14 Dec 2009)
New Revision: 4435
Modified:
trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp
Log:
Ticket 1184: SelectAggregate API causes connection leak
(http://trac.osgeo.org/mapguide/ticket/1184)
Submit on behalf of Aleck
Modified: trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp 2009-12-13 17:25:26 UTC (rev 4434)
+++ trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp 2009-12-14 07:59:27 UTC (rev 4435)
@@ -145,79 +145,95 @@
if (bFeatureJoinProperties)
{
// Perform feature join to obtain the joined properties
+ // Note: this gwsFeatureReader is just for temporary use. it will not be returned
+ // to the web-tier. Therefore this object must be closed to avoid connection leak
+ // I put the following code in a try-catch block just to make sure the gwsFeaturereader
+ // gets chance to be closed in case that an exception is thrown from underneath
Ptr<MgServerGwsFeatureReader> gwsFeatureReader = JoinFeatures(resource, className, NULL);
-
- // Get the requested property name from the MgFeatureServiceCommandObject. This property name may be
- // prefixed by the relation name if it is from a secondary resource.
- FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
- int nFicCnt = fic->GetCount();
- if (nFicCnt <= 0)
+ try
{
- // throw invalid argument exception because the properties the m_command is empty
- MgStringCollection arguments;
- arguments.Add(L"1");
- arguments.Add(L"MgFeatureServiceCommand");
+ // Get the requested property name from the MgFeatureServiceCommandObject. This property name may be
+ // prefixed by the relation name if it is from a secondary resource.
+ FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
+ int nFicCnt = fic->GetCount();
+ if (nFicCnt <= 0)
+ {
+ // throw invalid argument exception because the properties the m_command is empty
+ MgStringCollection arguments;
+ arguments.Add(L"1");
+ arguments.Add(L"MgFeatureServiceCommand");
- throw new MgInvalidArgumentException(L"MgServerSelectFeatures::SelectFeatures()",
- __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
+ throw new MgInvalidArgumentException(L"MgServerSelectFeatures::SelectFeatures()",
+ __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
- }
+ }
- FdoPtr<FdoIdentifier> fi = fic->GetItem(0);
- STRING propName = fi->GetName();
+ FdoPtr<FdoIdentifier> fi = fic->GetItem(0);
+ STRING propName = fi->GetName();
- // Parse the relation name from the property name by determining which source the property is from
- STRING relationName;
- STRING secClassName;
- STRING parsedPropertyName;
- IGWSFeatureIterator* gwsFeatureIter = NULL;
- gwsFeatureReader->ReadNext();
- gwsFeatureReader->DeterminePropertyFeatureSource(propName, &gwsFeatureIter, relationName, secClassName, parsedPropertyName);
+ // Parse the relation name from the property name by determining which source the property is from
+ STRING relationName;
+ STRING secClassName;
+ STRING parsedPropertyName;
+ IGWSFeatureIterator* gwsFeatureIter = NULL;
+ gwsFeatureReader->ReadNext();
+ gwsFeatureReader->DeterminePropertyFeatureSource(propName, &gwsFeatureIter, relationName, secClassName, parsedPropertyName);
- Ptr<MgResourceIdentifier> resId;
+ Ptr<MgResourceIdentifier> resId;
- // Get the resource id associated with the relation name
- if (relationName.empty())
- {
- // this is the primary resource
- resId = SAFE_ADDREF(resource);
- }
- else
- {
- // this is a secondary resource
- resId = GetSecondaryResourceIdentifier(resource, className, relationName);
- }
+ // Get the resource id associated with the relation name
+ if (relationName.empty())
+ {
+ // this is the primary resource
+ resId = SAFE_ADDREF(resource);
+ }
+ else
+ {
+ // this is a secondary resource
+ resId = GetSecondaryResourceIdentifier(resource, className, relationName);
+ }
- // Create new command to execute against the desired resource in defined by the join
- m_customPropertyFound = false;
- CreateCommand(resId, isSelectAggregate);
- // Set feature class name (either primary or secondary class)
- m_command->SetFeatureClassName((FdoString*)secClassName.c_str());
- // Set options
- m_options = SAFE_ADDREF(options);
+ // Create new command to execute against the desired resource in defined by the join
+ m_customPropertyFound = false;
+ CreateCommand(resId, isSelectAggregate);
+ // Set feature class name (either primary or secondary class)
+ m_command->SetFeatureClassName((FdoString*)secClassName.c_str());
+ // Set options
+ m_options = SAFE_ADDREF(options);
- // Update the value of the computed property. Since the joined property may be prefixed by the relation name
- // i.e. Join1PropA, this needs to be parsed into it individual relation and property components.
- Ptr<MgStringPropertyCollection> computedProperties = m_options->GetComputedProperties();
+ // Update the value of the computed property. Since the joined property may be prefixed by the relation name
+ // i.e. Join1PropA, this needs to be parsed into it individual relation and property components.
+ Ptr<MgStringPropertyCollection> computedProperties = m_options->GetComputedProperties();
- // Can only have one computed property for custom functions
- assert(computedProperties->GetCount() == 1);
- STRING aliasName = computedProperties->GetName(0);
- STRING expression = computedProperties->GetValue(0);
+ // Can only have one computed property for custom functions
+ assert(computedProperties->GetCount() == 1);
+ STRING aliasName = computedProperties->GetName(0);
+ STRING expression = computedProperties->GetValue(0);
- STRING::size_type nPropLength = propName.length();
- STRING::size_type nPropStart = expression.rfind(propName);
- STRING::size_type nPropEnd = expression.find(L")", nPropStart + 1);
+ STRING::size_type nPropLength = propName.length();
+ STRING::size_type nPropStart = expression.rfind(propName);
+ STRING::size_type nPropEnd = expression.find(L")", nPropStart + 1);
- STRING newExpression = expression.substr(0, nPropStart);
- newExpression += parsedPropertyName;
- newExpression += expression.substr(nPropStart + nPropLength);
- computedProperties->SetValue(aliasName, newExpression);
+ STRING newExpression = expression.substr(0, nPropStart);
+ newExpression += parsedPropertyName;
+ newExpression += expression.substr(nPropStart + nPropLength);
+ computedProperties->SetValue(aliasName, newExpression);
- // Apply options to FDO command
- ApplyQueryOptions(isSelectAggregate);
- if (bFeatureCalculation)
- UpdateCommandOnJoinCalculation(resource, className);
+ // Apply options to FDO command
+ ApplyQueryOptions(isSelectAggregate);
+ if (bFeatureCalculation)
+ UpdateCommandOnJoinCalculation(resource, className);
+ }
+ catch(...)
+ {
+ // Close the reader to avoid connection leak
+ gwsFeatureReader->Close();
+ throw;
+ }
+
+ // gwsFeatureReader will not be returned to the webtier. Therefore, we have to close it here since
+ // it is no longer neened. If we don't do this, the connection it owns will leak.
+ gwsFeatureReader->Close();
}
else if (bFeatureCalculation && !bFeatureJoinProperties)
UpdateCommandOnCalculation(resource, className);
More information about the mapguide-commits
mailing list