[mapguide-commits] r4367 - in trunk/MgDev/Server/src: Gws/GwsQueryEngine Gws/GwsQueryEngine/inc Gws/Include Services/Feature

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Dec 3 00:13:50 EST 2009


Author: leaf
Date: 2009-12-03 00:13:48 -0500 (Thu, 03 Dec 2009)
New Revision: 4367

Modified:
   trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsExtendedFeatureDescription.cpp
   trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsPreparedFeatureQuery.cpp
   trunk/MgDev/Server/src/Gws/GwsQueryEngine/inc/GwsQuery.h
   trunk/MgDev/Server/src/Gws/Include/GwsQueryEngine.h
   trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h
Log:
Ticket 1162: MgGwsFeatureReader does not work with left-out joins

http://trac.osgeo.org/mapguide/ticket/1162

submit on behalf of Aleck sun



Modified: trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsExtendedFeatureDescription.cpp
===================================================================
--- trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsExtendedFeatureDescription.cpp	2009-12-03 02:22:06 UTC (rev 4366)
+++ trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsExtendedFeatureDescription.cpp	2009-12-03 05:13:48 UTC (rev 4367)
@@ -52,6 +52,7 @@
     m_joinName = other.m_joinName;
     m_joinDelimiter = other.m_joinDelimiter;
     m_forceOneToOne = other.m_forceOneToOne;
+    m_leftOuterJoin = other.m_leftOuterJoin;
     CGwsQueryResultDescriptors & src = (CGwsQueryResultDescriptors &) other;
     for (int i = 0; i < src.GetCount (); i ++) {
         FdoPtr<IGWSExtendedFeatureDescription> fdsc = src.GetItem (i);
@@ -66,7 +67,8 @@
     const FdoString        * joinName,
     const FdoString        * joinDelimiter,
     bool                     forceOneToOne,
-    FdoIdentifierCollection    * propnames
+    FdoIdentifierCollection    * propnames,
+    bool                     leftOuterJoin
 )
 {
     m_classDef = classDef;
@@ -78,6 +80,7 @@
     if(NULL != joinDelimiter)
         m_joinDelimiter = joinDelimiter;
     m_forceOneToOne = forceOneToOne;
+    m_leftOuterJoin = leftOuterJoin;
     m_propertynames = FdoStringCollection::Create ();
     appendPropertyNames (propnames, classDef, m_propertynames, m_propdsc);
     if( propnames != NULL )

Modified: trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsPreparedFeatureQuery.cpp
===================================================================
--- trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsPreparedFeatureQuery.cpp	2009-12-03 02:22:06 UTC (rev 4366)
+++ trunk/MgDev/Server/src/Gws/GwsQueryEngine/GwsPreparedFeatureQuery.cpp	2009-12-03 05:13:48 UTC (rev 4367)
@@ -169,7 +169,7 @@
             m_resultDescriptor->Release();
         }
         if(jqd)
-            m_resultDescriptor = new CGwsQueryResultDescriptors (m_classDef, m_classname, jqd->JoinName(), jqd->JoinDelimiter(), jqd->ForceOneToOne(), sellist);
+            m_resultDescriptor = new CGwsQueryResultDescriptors (m_classDef, m_classname, jqd->JoinName(), jqd->JoinDelimiter(), jqd->ForceOneToOne(), sellist, qDef->Type() == eGwsQueryLeftOuterJoin);
         else
             m_resultDescriptor = new CGwsQueryResultDescriptors (m_classDef, m_classname, NULL, NULL, true, sellist);
         m_resultDescriptor->AddRef ();

Modified: trunk/MgDev/Server/src/Gws/GwsQueryEngine/inc/GwsQuery.h
===================================================================
--- trunk/MgDev/Server/src/Gws/GwsQueryEngine/inc/GwsQuery.h	2009-12-03 02:22:06 UTC (rev 4366)
+++ trunk/MgDev/Server/src/Gws/GwsQueryEngine/inc/GwsQuery.h	2009-12-03 05:13:48 UTC (rev 4367)
@@ -180,7 +180,8 @@
                                             const FdoString        * joinName,
                                             const FdoString        * joinDelimiter,
                                             bool                     forceOneToOne,
-                                            FdoIdentifierCollection    * propnames);
+                                            FdoIdentifierCollection    * propnames,
+                                            bool                   leftOuterJoin = false);
     GWS_QUERYENGINE_API             CGwsQueryResultDescriptors (const CGwsQueryResultDescriptors & other);
     GWS_QUERYENGINE_API
     virtual                         ~CGwsQueryResultDescriptors () throw();
@@ -229,6 +230,7 @@
     void                             SetCSName (const GWSCoordinateSystem & csname);
 
     virtual bool                    ForceOneToOneJoin() { return m_forceOneToOne; }
+    virtual bool                    LeftOuterJoin() { return m_leftOuterJoin; };
 
 protected:
      void                           appendPropertyNames (
@@ -255,6 +257,7 @@
     WSTR                                m_joinName;
     WSTR                                m_joinDelimiter;
     bool                                m_forceOneToOne;
+    bool                                m_leftOuterJoin;
 
     // joined properties
     std::vector<IGWSExtendedFeatureDescription*>

Modified: trunk/MgDev/Server/src/Gws/Include/GwsQueryEngine.h
===================================================================
--- trunk/MgDev/Server/src/Gws/Include/GwsQueryEngine.h	2009-12-03 02:22:06 UTC (rev 4366)
+++ trunk/MgDev/Server/src/Gws/Include/GwsQueryEngine.h	2009-12-03 05:13:48 UTC (rev 4367)
@@ -411,6 +411,12 @@
     /// </summary>
     /// <returns>Returns the force one to one flag.</returns>
     virtual bool ForceOneToOneJoin() = 0;
+
+    /// </summary>
+    /// Returns whether the join is a left outer join.
+    /// </summary>
+    /// <returns>Returns whether the join is a left outer join.</returns>
+    virtual bool LeftOuterJoin() = 0;
 };
 
 

Modified: trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp	2009-12-03 02:22:06 UTC (rev 4366)
+++ trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp	2009-12-03 05:13:48 UTC (rev 4367)
@@ -219,11 +219,23 @@
                             {
                                 // Since key values in this Pair do not need to be unqiue, we will use it to store the delimiter string that is defined
                                 // for the extended properties that originate from this secondary feature source
-                                m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, secondaryIter));
+                                m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, GwsRightSideIterator(secondaryIter,true)));
                             }
                             else
                             {
-                                m_bAdvancePrimaryIterator = true;
+                                FdoPtr<IGWSExtendedFeatureDescription> pDesc = m_primaryExtendedFeatureDescription->GetItem(i);
+                                if(pDesc->LeftOuterJoin())
+                                {
+                                    // Fix ticket #1162
+                                    // If we are processing left-outer joins, we don't skip the left side feature even though
+                                    // there is no right side feature exists.
+                                    m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, GwsRightSideIterator(secondaryIter,false)));
+                                    retVal = true;
+                                }
+                                else
+                                {
+                                    m_bAdvancePrimaryIterator = true;
+                                }
                             }
                         }
                         else
@@ -264,7 +276,7 @@
                 if (m_secondaryGwsFeatureIteratorMap.size() > 0)
                 {
                     iter = m_secondaryGwsFeatureIteratorMap.begin();
-                    secondaryFeatureIter = iter->second;
+                    secondaryFeatureIter = iter->second.Iterator();
                     retVal = secondaryFeatureIter->ReadNext();
                 }
 
@@ -277,7 +289,7 @@
                     if (m_secondaryGwsFeatureIteratorMap.size() > 0)
                     {
                         iter = m_secondaryGwsFeatureIteratorMap.begin();
-                        secondaryFeatureIter = iter->second;
+                        secondaryFeatureIter = iter->second.Iterator();
                         retVal = secondaryFeatureIter->ReadNext();
                     }
                 }
@@ -324,11 +336,23 @@
                                     {
                                         // Since key values in this Pair do not need to be unqiue, we will use it to store the delimiter string that is defined
                                         // for the extended properties that originate from this secondary feature source
-                                        m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, featureIter2));
+                                        m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, GwsRightSideIterator(featureIter2,true)));
                                     }
                                     else
                                     {
-                                        m_bAdvancePrimaryIterator = true;
+                                        FdoPtr<IGWSExtendedFeatureDescription> pDesc = m_primaryExtendedFeatureDescription->GetItem(i);
+                                        if(pDesc->LeftOuterJoin())
+                                        {
+                                            // Fix ticket #1162
+                                            // If we are processing left-outer joins, we don't skip the left side feature even though
+                                            // there is no right side feature exists.
+                                            m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, GwsRightSideIterator(featureIter2,false)));
+                                            retVal = true;
+                                        }
+                                        else
+                                        {
+                                            m_bAdvancePrimaryIterator = true;
+                                        }
                                     }
                                 }
                                 else
@@ -1232,7 +1256,7 @@
              iter != m_secondaryGwsFeatureIteratorMap.end();
              iter++)
         {
-            IGWSFeatureIterator* pSecondaryFeatureIter = iter->second;
+            IGWSFeatureIterator* pSecondaryFeatureIter = iter->second.Iterator();
             if (pSecondaryFeatureIter)
             {
                 pSecondaryFeatureIter->Close();
@@ -1418,7 +1442,7 @@
              iter != m_secondaryGwsFeatureIteratorMap.end();
              iter++)
         {
-            secondaryFeatureIter = iter->second;
+            secondaryFeatureIter = iter->second.Iterator();
             CHECKNULL(secondaryFeatureIter, L"MgServerGwsFeatureReader.DeterminePropertyFeatureSource");
 
             FdoPtr<IGWSExtendedFeatureDescription> secondaryDesc;
@@ -1443,7 +1467,7 @@
 
                 if ( wcscmp(featureSource, relationName.c_str()) == 0 )
                 {
-                    *gwsFeatureIter = secondaryFeatureIter;
+                    *gwsFeatureIter = iter->second.HasData() ? secondaryFeatureIter : NULL;
                     className = (wchar_t*)fclassName;
                     iter = m_secondaryGwsFeatureIteratorMap.end();
                     iter--;
@@ -1746,7 +1770,7 @@
 
                         if (featureIter->ReadNext())
                         {
-                            m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, featureIter));
+                            m_secondaryGwsFeatureIteratorMap.insert(GwsFeatureIteratorPair(attributeNameDelimiter, GwsRightSideIterator(featureIter,false)));
                             secFdoClassDefinition = featureIter->GetClassDefinition();
                         }
                         else

Modified: trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h	2009-12-03 02:22:06 UTC (rev 4366)
+++ trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h	2009-12-03 05:13:48 UTC (rev 4367)
@@ -22,9 +22,28 @@
 #include "ServerFeatureServiceDefs.h"
 #include "GwsQueryEngine.h"
 
-typedef std::multimap<STRING, IGWSFeatureIterator*> GwsFeatureIteratorMap;
-typedef std::pair<STRING, IGWSFeatureIterator*> GwsFeatureIteratorPair;
+class GwsRightSideIterator
+{
+public:
+    GwsRightSideIterator(IGWSFeatureIterator* iter, bool b):m_iterator(iter), m_bHasData(b){}
+    
+    IGWSFeatureIterator * Iterator(){return m_iterator;};
+    bool HasData(){return m_bHasData;}
 
+private:
+    IGWSFeatureIterator* m_iterator;
+
+    // Fix ticket #1162
+    // When we are processing left-outer joins, this field is needed because we need the iterator
+    // to describe the right-side result. In the meanwhile, we need a flag to indicate that this
+    // iterator does not contains data, and we will return all null value for the right side
+    // features
+    bool                m_bHasData;
+};
+
+typedef std::multimap<STRING, GwsRightSideIterator> GwsFeatureIteratorMap;
+typedef std::pair<STRING, GwsRightSideIterator> GwsFeatureIteratorPair;
+
 class MgJoinFeatureReader;
 class FdoExpressionEngine;
 class FdoFilter;



More information about the mapguide-commits mailing list