[mapguide-commits] r6903 - in branches/2.4/MgDev/Desktop/MgDesktop: . Services Services/Feature Services/Feature/Commands
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Sun Jul 15 09:59:27 PDT 2012
Author: jng
Date: 2012-07-15 09:59:27 -0700 (Sun, 15 Jul 2012)
New Revision: 6903
Added:
branches/2.4/MgDev/Desktop/MgDesktop/Services/CryptoDefs.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.h
Removed:
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h
Modified:
branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDefs.h
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.cpp
branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.h
Log:
mg-desktop changes:
- Graft a significant chunk of the MgServerFeatureService project (commands and supporting classes) into mg-desktop. Rather than re-implementing most of the MgFeatureService APIs from scratch with mixed results, let's just re-use the already vetted code and logic from that library. This will not only eventually fix #2074, but also shrink down the size of FeatureService.cpp
Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj 2012-07-15 15:04:11 UTC (rev 6902)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj 2012-07-15 16:59:27 UTC (rev 6903)
@@ -400,6 +400,42 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\ApplySchema.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\Resource\ByteSourceDwfInputStreamImpl.cpp"
>
<FileConfiguration
@@ -688,6 +724,42 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\DeleteCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\DrawingService.cpp"
>
<FileConfiguration
@@ -1048,6 +1120,78 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\FdoFeatureReader.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\FdoFilterCollection.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\Feature\FdoForcedOneToOneFeatureReader.cpp"
>
<FileConfiguration
@@ -1084,6 +1228,42 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\FdoReaderCollection.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\Feature\FeatureClassCacheItem.cpp"
>
<FileConfiguration
@@ -1300,6 +1480,42 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\FeatureManipulationCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\Feature\FeatureNumericFunctions.cpp"
>
<FileConfiguration
@@ -1516,6 +1732,78 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\FeatureServiceCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\FeatureSetReader.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\Feature\FeatureSourceCacheItem.cpp"
>
<FileConfiguration
@@ -1624,6 +1912,222 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\GetConnectionPropertyValues.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetFeatureProviders.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetLongTransactions.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetProviderCapabilities.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetSchemaMapping.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetSpatialContexts.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\Feature\GwsConnectionPool.cpp"
>
<FileConfiguration
@@ -1732,6 +2236,42 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\InsertCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Exception\InvalidDwfPackageException.cpp"
>
<FileConfiguration
@@ -3320,6 +3860,114 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\SelectAggregateCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\SelectCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\SelectFeatures.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\MapLayer\Selection.cpp"
>
<FileConfiguration
@@ -3464,6 +4112,42 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\SqlCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\SqlReader.cpp"
>
<FileConfiguration
@@ -3896,6 +4580,78 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\UpdateCommand.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\UpdateFeatures.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\Services\Resource\ZipFileHandler.cpp"
>
<FileConfiguration
@@ -3978,6 +4734,10 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\ApplySchema.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\BooleanDataReaderCreator.h"
>
</File>
@@ -4010,6 +4770,10 @@
>
</File>
<File
+ RelativePath=".\Services\CryptoDefs.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Rendering\CustomLogoInfo.h"
>
</File>
@@ -4030,6 +4794,10 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\DeleteCommand.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\DoubleDataReaderCreator.h"
>
</File>
@@ -4078,10 +4846,22 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\FdoFeatureReader.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\FdoFilterCollection.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\FdoForcedOneToOneFeatureReader.h"
>
</File>
<File
+ RelativePath=".\Services\Feature\FdoReaderCollection.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\FeatureClassCacheItem.h"
>
</File>
@@ -4110,6 +4890,10 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\FeatureManipulationCommand.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\FeatureNumericFunctions.h"
>
</File>
@@ -4134,6 +4918,14 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\FeatureServiceCommand.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\FeatureSetReader.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\FeatureSourceCacheItem.h"
>
</File>
@@ -4146,14 +4938,34 @@
>
</File>
<File
- RelativePath=".\Services\Feature\FeautreNumericFunctions.h"
+ RelativePath=".\Services\Feature\GeometryDataReaderCreator.h"
>
</File>
<File
- RelativePath=".\Services\Feature\GeometryDataReaderCreator.h"
+ RelativePath=".\Services\Feature\Commands\GetConnectionPropertyValues.h"
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\GetFeatureProviders.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetLongTransactions.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetProviderCapabilities.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetSchemaMapping.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\GetSpatialContexts.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\GwsConnectionPool.h"
>
</File>
@@ -4170,6 +4982,10 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\InsertCommand.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Feature\Int16DataReaderCreator.h"
>
</File>
@@ -4386,6 +5202,18 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\SelectAggregateCommand.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\SelectCommand.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\SelectFeatures.h"
+ >
+ </File>
+ <File
RelativePath=".\MapLayer\Selection.h"
>
</File>
@@ -4406,6 +5234,10 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\SqlCommand.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\SqlReader.h"
>
</File>
@@ -4462,6 +5294,14 @@
>
</File>
<File
+ RelativePath=".\Services\Feature\Commands\UpdateCommand.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services\Feature\Commands\UpdateFeatures.h"
+ >
+ </File>
+ <File
RelativePath=".\Services\Resource\ZipFileHandler.h"
>
</File>
Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp 2012-07-15 15:04:11 UTC (rev 6902)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -49,7 +49,10 @@
#include "Services/Feature/CreateFeatureSource.cpp"
#include "Services/Feature/FdoConnectionPool.cpp"
#include "Services/Feature/FdoConnectionUtil.cpp"
+#include "Services/Feature/FdoFeatureReader.cpp"
+#include "Services/Feature/FdoFilterCollection.cpp"
#include "Services/Feature/FdoForcedOneToOneFeatureReader.cpp"
+#include "Services/Feature/FdoReaderCollection.cpp"
#include "Services/Feature/FeatureClassCacheItem.cpp"
#include "Services/Feature/FeatureConnection.cpp"
#include "Services/Feature/FeatureDistribution.cpp"
@@ -58,6 +61,7 @@
#include "Services/Feature/FeatureSchemaCacheItem.cpp"
#include "Services/Feature/FeatureServiceCacheEntry.cpp"
#include "Services/Feature/FeatureServiceCache.cpp"
+#include "Services/Feature/FeatureSetReader.cpp"
#include "Services/Feature/FeatureSourceCacheItem.cpp"
#include "Services/Feature/FeatureStringFunctions.cpp"
#include "Services/Feature/FeatureUtil.cpp"
@@ -71,6 +75,23 @@
#include "Services/Feature/RdbmsFeatureSourceParams.cpp"
#include "Services/Feature/SpatialContextCacheItem.cpp"
#include "Services/Feature/TransformCache.cpp"
+#include "Services/Feature/Commands/ApplySchema.cpp"
+#include "Services/Feature/Commands/DeleteCommand.cpp"
+#include "Services/Feature/Commands/FeatureManipulationCommand.cpp"
+#include "Services/Feature/Commands/FeatureServiceCommand.cpp"
+#include "Services/Feature/Commands/GetConnectionPropertyValues.cpp"
+#include "Services/Feature/Commands/GetFeatureProviders.cpp"
+#include "Services/Feature/Commands/GetLongTransactions.cpp"
+#include "Services/Feature/Commands/GetProviderCapabilities.cpp"
+#include "Services/Feature/Commands/GetSchemaMapping.cpp"
+#include "Services/Feature/Commands/GetSpatialContexts.cpp"
+#include "Services/Feature/Commands/InsertCommand.cpp"
+#include "Services/Feature/Commands/SelectAggregateCommand.cpp"
+#include "Services/Feature/Commands/SelectCommand.cpp"
+#include "Services/Feature/Commands/SelectFeatures.cpp"
+#include "Services/Feature/Commands/SqlCommand.cpp"
+#include "Services/Feature/Commands/UpdateCommand.cpp"
+#include "Services/Feature/Commands/UpdateFeatures.cpp"
#include "Services/Rendering/CustomLogoInfo.cpp"
#include "Services/Rendering/CustomTextInfo.cpp"
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/CryptoDefs.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/CryptoDefs.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/CryptoDefs.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,113 @@
+#ifndef DESKTOP_CRYPTO_DEFS_H
+#define DESKTOP_CRYPTO_DEFS_H
+
+#include "SecurityDefs.h"
+#include "CryptographyUtil.h"
+
+///////////////////////////////////////////////////////////////////////////////
+/// Helper macros.
+///
+#define MG_CRYPTOGRAPHY_TRY() \
+ Ptr<MgException> cryptographyException; \
+ \
+ try \
+ { \
+
+#define MG_CRYPTOGRAPHY_CATCH(methodName) \
+ } \
+ catch (MgErrorCode errorCode) \
+ { \
+ switch (errorCode) \
+ { \
+ case ecOk: \
+ break; \
+ \
+ case ecInvalidOperation: \
+ cryptographyException = new MgInvalidOperationException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecNullArgument: \
+ cryptographyException = new MgNullArgumentException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecInvalidArgument: \
+ cryptographyException = new MgInvalidArgumentException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecLengthError: \
+ cryptographyException = new MgLengthException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecDateTimeError: \
+ cryptographyException = new MgDateTimeException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecFileIoError: \
+ case ecReadError: \
+ case ecWriteError: \
+ cryptographyException = new MgFileIoException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecEncryptionError: \
+ cryptographyException = new MgEncryptionException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecDecryptionError: \
+ cryptographyException = new MgDecryptionException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ \
+ case ecUnclassified: \
+ default: \
+ cryptographyException = new MgUnclassifiedException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ break; \
+ } \
+ } \
+ catch (MgException* e) \
+ { \
+ cryptographyException = e; \
+ cryptographyException->AddStackTraceInfo( \
+ methodName, __LINE__, __WFILE__); \
+ } \
+ catch (exception& e) \
+ { \
+ cryptographyException = MgSystemException::Create( \
+ e, methodName, __LINE__, __WFILE__); \
+ } \
+ catch (...) \
+ { \
+ cryptographyException = new MgUnclassifiedException( \
+ methodName, __LINE__, __WFILE__, NULL, L"", NULL); \
+ } \
+
+#define MG_CRYPTOGRAPHY_THROW() \
+ if (cryptographyException != NULL) \
+ { \
+ (*cryptographyException).AddRef(); \
+ cryptographyException->Raise(); \
+ } \
+
+#define MG_CRYPTOGRAPHY_CATCH_AND_THROW(methodName) \
+ MG_CRYPTOGRAPHY_CATCH(methodName) \
+ \
+ MG_CRYPTOGRAPHY_THROW() \
+
+#define MG_CRYPTOGRAPHY_CATCH_AND_RELEASE() \
+ } \
+ catch (MgException* e) \
+ { \
+ cryptographyException = e; \
+ } \
+ catch (...) \
+ { \
+ } \
+
+#endif
\ No newline at end of file
Property changes on: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands
___________________________________________________________________
Added: bugtraq:number
+ true
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,106 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "ApplySchema.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "Services/Feature/FeatureServiceCache.h"
+
+//////////////////////////////////////////////////////////////////
+MgServerApplySchema::MgServerApplySchema()
+{
+}
+
+//////////////////////////////////////////////////////////////////
+MgServerApplySchema::~MgServerApplySchema()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void MgServerApplySchema::ApplySchema(MgResourceIdentifier* resource,
+ MgFeatureSchema* schema)
+{
+ MG_FEATURE_SERVICE_TRY()
+
+ if (NULL == resource || NULL == schema)
+ {
+ throw new MgNullArgumentException(L"MgServerApplySchema.ApplySchema", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ // Connect to provider
+ Ptr<MgFeatureConnection> msfc = new MgFeatureConnection(resource);
+
+ // connection must be open
+ bool bRefresh = false;
+ if ((NULL != msfc.p) && ( msfc->IsConnectionOpen() ))
+ {
+ FdoPtr<FdoIConnection> fdoConn = msfc->GetConnection();
+
+ // Check whether command is supported by provider
+ if (!msfc->SupportsCommand((INT32)FdoCommandType_ApplySchema) ||
+ !msfc->SupportsCommand((INT32)FdoCommandType_DescribeSchema))
+ {
+ // TODO: specify which argument and message, once we have the mechanism
+ STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
+ throw new MgInvalidOperationException(L"MgServerApplySchema.ApplySchema", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ FdoPtr<FdoIDescribeSchema> fdoDecribeSchemaCmd = (FdoIDescribeSchema*) fdoConn->CreateCommand(FdoCommandType_DescribeSchema);
+ CHECKNULL((FdoIDescribeSchema*)fdoDecribeSchemaCmd, L"MgServerApplySchema.ApplySchema");
+
+ FdoPtr<FdoFeatureSchemaCollection> schemas = fdoDecribeSchemaCmd->Execute();
+ CHECKNULL((FdoFeatureSchemaCollection*)schemas, L"MgServerApplySchema.ApplySchema");
+
+ FdoPtr<FdoIApplySchema> fdoApplySchemaCmd = (FdoIApplySchema*)fdoConn->CreateCommand(FdoCommandType_ApplySchema);
+ CHECKNULL((FdoIApplySchema*)fdoApplySchemaCmd, L"MgServerApplySchema.ApplySchema");
+
+ STRING schemaName = schema->GetName();
+ FdoPtr<FdoFeatureSchema> fdoOldSchema = schemas->FindItem(schemaName.c_str());
+ if (NULL == fdoOldSchema)
+ {
+ if (!schema->IsDeleted())
+ {
+ FdoPtr<FdoFeatureSchema> fdoNewSchema = MgFeatureUtil::GetFdoFeatureSchema(schema);
+ fdoApplySchemaCmd->SetFeatureSchema(fdoNewSchema);
+ fdoApplySchemaCmd->Execute();
+ bRefresh = true;
+ }
+ }
+ else
+ {
+ if (!schema->IsDeleted())
+ MgFeatureUtil::UpdateFdoFeatureSchema(schema, fdoOldSchema);
+ else
+ fdoOldSchema->Delete();
+
+ fdoApplySchemaCmd->SetFeatureSchema(fdoOldSchema);
+ fdoApplySchemaCmd->Execute();
+ bRefresh = true;
+ }
+ }
+
+ // Clear the cached schema so that MgFeatureService::DescribeSchema
+ // can return the correct schema
+ if (bRefresh)
+ {
+ MgFeatureServiceCache* m_cacheManager = MgFeatureServiceCache::GetInstance();
+ m_cacheManager->RemoveEntry(resource);
+ }
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerDescribeSchema.ApplySchema")
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/ApplySchema.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef MG_SERVER_APPLY_SCHEMA_H_
+#define MG_SERVER_APPLY_SCHEMA_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+#include "FSDSAX2Parser.h"
+
+class MgServerApplySchema
+{
+/// Constructors/Destructor
+public:
+ MgServerApplySchema();
+ ~MgServerApplySchema();
+public:
+ void ApplySchema(MgResourceIdentifier* resource, MgFeatureSchema* schema);
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,69 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "FeatureManipulationCommand.h"
+#include "DeleteCommand.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "Services/FeatureReader.h"
+
+MgServerDeleteCommand::MgServerDeleteCommand()
+{
+ m_srvrFeatConn = NULL;
+ m_featCommand = NULL;
+}
+
+MgServerDeleteCommand::MgServerDeleteCommand(MgFeatureCommand* command, MgFeatureConnection* connection, INT32 cmdId)
+{
+ CHECKNULL(command, L"MgServerDeleteCommand.MgServerDeleteCommand");
+ CHECKNULL(connection, L"MgServerDeleteCommand.MgServerDeleteCommand");
+
+ m_srvrFeatConn = SAFE_ADDREF((MgFeatureConnection*)connection);
+ m_featCommand = SAFE_ADDREF((MgDeleteFeatures*)command);
+ m_cmdId = cmdId;
+}
+
+MgServerDeleteCommand::~MgServerDeleteCommand()
+{
+ m_srvrFeatConn = NULL;
+}
+
+MgProperty* MgServerDeleteCommand::Execute()
+{
+ STRING clsName = m_featCommand->GetFeatureClassName();
+ STRING filterText = m_featCommand->GetFilterText();
+
+ FdoPtr<FdoIConnection> fdoConn = m_srvrFeatConn->GetConnection();
+
+ // Create the SQL command
+ FdoPtr<FdoIDelete> fdoCommand = (FdoIDelete*)fdoConn->CreateCommand(FdoCommandType_Delete);
+ CHECKNULL((FdoIDelete*)fdoCommand, L"MgServerDeleteCommand.Execute");
+
+ fdoCommand->SetFeatureClassName(clsName.c_str());
+ fdoCommand->SetFilter(filterText.c_str());
+
+ INT32 recordsDeleted = fdoCommand->Execute();
+
+ char buff[32];
+ sprintf(buff, "%d", m_cmdId);
+ STRING str = MgUtil::MultiByteToWideChar(string(buff));
+
+ return new MgInt32Property(str, recordsDeleted);
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/DeleteCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_DELETE_COMMAND_H_
+#define _MG_SERVER_DELETE_COMMAND_H_
+
+class MgFeatureConnection;
+
+class MgServerDeleteCommand : public MgFeatureManipulationCommand
+{
+ DECLARE_CLASSNAME(MgServerDeleteCommand)
+
+public:
+ MgServerDeleteCommand(MgFeatureCommand* command, MgFeatureConnection* connection, INT32 cmdId);
+ virtual MgProperty* Execute();
+protected:
+ MgServerDeleteCommand();
+ ~MgServerDeleteCommand();
+private:
+ Ptr<MgDeleteFeatures> m_featCommand;
+ Ptr<MgFeatureConnection> m_srvrFeatConn;
+ INT32 m_cmdId;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,79 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "FeatureManipulationCommand.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "InsertCommand.h"
+#include "UpdateCommand.h"
+#include "DeleteCommand.h"
+
+MgFeatureManipulationCommand* MgFeatureManipulationCommand::CreateCommand(MgFeatureCommand* webCmd, MgFeatureConnection* connection, INT32 cmdId)
+{
+ CHECKNULL(webCmd, L"MgFeatureManipulationCommand.CreateCommand")
+ CHECKNULL(connection, L"MgFeatureManipulationCommand.CreateCommand")
+
+ INT32 cmdType = webCmd->GetCommandType();
+ bool supports = false;
+
+ Ptr<MgFeatureManipulationCommand> command;
+
+ switch(cmdType)
+ {
+ case MgFeatureCommandType::InsertFeatures:
+ {
+ supports = connection->SupportsCommand(FdoCommandType_Insert);
+ if (supports)
+ {
+ command = new MgServerInsertCommand(webCmd, connection, cmdId);
+ }
+ break;
+ }
+ case MgFeatureCommandType::UpdateFeatures:
+ {
+ supports = connection->SupportsCommand(FdoCommandType_Update);
+ if (supports)
+ {
+ command = new MgServerUpdateCommand(webCmd, connection, cmdId);
+ }
+ break;
+ }
+ case MgFeatureCommandType::DeleteFeatures:
+ {
+ supports = connection->SupportsCommand(FdoCommandType_Delete);
+ if (supports)
+ {
+ command = new MgServerDeleteCommand(webCmd, connection, cmdId);
+ }
+ break;
+ }
+ }
+
+ if (!supports)
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgFeatureManipulationCommand.CreateCommand", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ return command.Detach();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureManipulationCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_FEATURE_MANIPULATION_COMMAND_H_
+#define _MG_FEATURE_MANIPULATION_COMMAND_H_
+
+class MgFeatureConnection;
+
+class MgFeatureManipulationCommand : public MgDisposable
+{
+public:
+ static MgFeatureManipulationCommand* CreateCommand(MgFeatureCommand* command, MgFeatureConnection* connection, INT32 cmdId);
+ virtual MgProperty* Execute() = 0;
+protected:
+ virtual void Dispose()
+ {
+ delete this;
+ }
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,116 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "FeatureServiceCommand.h"
+#include "SelectCommand.h"
+#include "SelectAggregateCommand.h"
+
+MgFeatureServiceCommand* MgFeatureServiceCommand::CreateCommand(MgResourceIdentifier* resource, FdoCommandType commandType)
+{
+ Ptr<MgFeatureServiceCommand> command;
+ switch(commandType)
+ {
+ case FdoCommandType_Select:
+ {
+ command = new MgSelectCommand(resource);
+ break;
+ }
+ case FdoCommandType_SelectAggregates:
+ {
+ command = new MgSelectAggregateCommand(resource);
+ break;
+ }
+ }
+ return command.Detach();
+}
+
+bool MgFeatureServiceCommand::IsFdoSupportedFunction(FdoIConnection* connection, FdoFunction* fdoFunc)
+{
+ CHECKNULL(connection, L"MgServerSelectFeatures.SupportsFunction");
+
+ FdoPtr<FdoIExpressionCapabilities> fec = connection->GetExpressionCapabilities();
+ CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgServerSelectFeatures.SupportsFunction");
+
+ bool supports = false;
+
+ FdoPtr<FdoFunctionDefinitionCollection> ffdc = fec->GetFunctions();
+ if (NULL != (FdoFunctionDefinitionCollection*)ffdc)
+ {
+ FdoInt32 funcCnt = ffdc->GetCount();
+ for (FdoInt32 i=0; i < funcCnt; i++)
+ {
+ FdoPtr<FdoFunctionDefinition> ffd = ffdc->GetItem(i);
+ CHECKNULL((FdoFunctionDefinition*)ffd, L"MgServerSelectFeatures.SupportsFunction");
+
+ // TODO: Just comparing name is enough?
+ // TODO: I think, NOT, because there can be overloaded functions like one function
+ // with multiple arguments, differnet datatypes etc.
+ //
+ // Comparing argument count is not sufficient because, there can be optional arguments
+ // as well. Therefore, we should just restrict to name comparision only
+ FdoString* funcNameAllowed = ffd->GetName();
+ FdoString* funcNameSupplied = fdoFunc->GetName();
+ size_t cmp = _wcsicmp(funcNameAllowed, funcNameSupplied);
+ if (cmp == 0)
+ {
+ supports = true;
+ break;
+ }
+ }
+ }
+ return supports;
+}
+
+bool MgFeatureServiceCommand::SupportsSelectDistinct(FdoIConnection* connection)
+{
+ CHECKNULL((FdoIConnection*)connection, L"MgFeatureServiceCommand.SupportsSelectDistinct");
+
+ FdoPtr<FdoICommandCapabilities> fcc = connection->GetCommandCapabilities();
+ CHECKNULL((FdoICommandCapabilities*)fcc, L"MgFeatureServiceCommand.SupportsSelectDistinct");
+
+ bool supports = fcc->SupportsSelectDistinct();
+
+ return supports;
+}
+
+
+bool MgFeatureServiceCommand::SupportsSelectOrdering(FdoIConnection* connection)
+{
+ CHECKNULL((FdoIConnection*)connection, L"MgFeatureServiceCommand.SupportsSelectOrdering");
+
+ FdoPtr<FdoICommandCapabilities> fcc = connection->GetCommandCapabilities();
+ CHECKNULL((FdoICommandCapabilities*)fcc, L"MgFeatureServiceCommand.SupportsSelectOrdering");
+
+ bool supports = fcc->SupportsSelectOrdering();
+
+ return supports;
+}
+
+bool MgFeatureServiceCommand::SupportsSelectGrouping(FdoIConnection* connection)
+{
+ CHECKNULL((FdoIConnection*)connection, L"MgFeatureServiceCommand.SupportsSelectGrouping");
+
+ FdoPtr<FdoICommandCapabilities> fcc = connection->GetCommandCapabilities();
+ CHECKNULL((FdoICommandCapabilities*)fcc, L"MgFeatureServiceCommand.SupportsSelectGrouping");
+
+ bool supports = fcc->SupportsSelectGrouping();
+
+ return supports;
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/FeatureServiceCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,63 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MGFEATURESERVICECOMMAND_H_
+#define _MGFEATURESERVICECOMMAND_H_
+
+class MgFeatureServiceCommand : public MgDisposable
+{
+public:
+ static MgFeatureServiceCommand* CreateCommand(MgResourceIdentifier* resource, FdoCommandType commandType);
+
+ virtual FdoIdentifierCollection* GetPropertyNames() = 0;
+
+ virtual void SetDistinct( bool value ) = 0;
+ virtual bool GetDistinct( ) = 0;
+
+ virtual void SetFetchSize(FdoInt32 fetchSize) = 0;
+ virtual FdoInt32 GetFetchSize() = 0;
+
+ virtual FdoIdentifierCollection* GetOrdering() = 0;
+ virtual void SetOrderingOption( FdoOrderingOption option ) = 0;
+ virtual FdoOrderingOption GetOrderingOption( ) = 0;
+
+ virtual FdoIdentifierCollection* GetGrouping() = 0;
+ virtual void SetGroupingFilter( FdoFilter* filter ) = 0;
+ virtual FdoFilter* GetGroupingFilter( ) = 0;
+
+ virtual void SetFeatureClassName(FdoString* value) = 0;
+ virtual void SetFilter(FdoString* value) = 0;
+ virtual void SetFilter(FdoFilter* value) = 0;
+
+ virtual FdoFilter* GetFilter() = 0;
+
+ virtual bool IsSupportedFunction(FdoFunction* fdoFunc) = 0;
+ virtual bool SupportsSelectGrouping() = 0;
+ virtual bool SupportsSelectOrdering() = 0;
+ virtual bool SupportsSelectDistinct() = 0;
+
+ virtual MgReader* Execute() = 0;
+
+protected:
+
+ virtual bool IsFdoSupportedFunction(FdoIConnection* connection, FdoFunction* fdoFunc);
+ virtual bool SupportsSelectGrouping(FdoIConnection* connection);
+ virtual bool SupportsSelectOrdering(FdoIConnection* connection);
+ virtual bool SupportsSelectDistinct(FdoIConnection* connection);
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,136 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "GetConnectionPropertyValues.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "Services/CryptoDefs.h"
+
+MgServerGetConnectionPropertyValues::MgServerGetConnectionPropertyValues()
+{
+}
+
+MgServerGetConnectionPropertyValues::~MgServerGetConnectionPropertyValues()
+{
+}
+
+// Executes the describe schema command and serializes the schema to XML
+MgStringCollection* MgServerGetConnectionPropertyValues::GetConnectionPropertyValues( CREFSTRING providerName,
+ CREFSTRING propertyName,
+ CREFSTRING partialConnString )
+{
+ Ptr<MgStringCollection> stringCol;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ if (providerName.empty())
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"1");
+ arguments.Add(MgResources::BlankArgument);
+
+ throw new MgInvalidArgumentException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues",
+ __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
+ }
+
+ if (propertyName.empty())
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"2");
+ arguments.Add(MgResources::BlankArgument);
+
+ throw new MgInvalidArgumentException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues",
+ __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
+ }
+
+ // Decrypt the partial connection string if it was encrypted.
+
+ STRING decryptedPartialConnString;
+
+ {
+ MG_CRYPTOGRAPHY_TRY()
+
+ MgCryptographyUtil cryptoUtil;
+ string cipherText, plainText;
+
+ MgUtil::WideCharToMultiByte(partialConnString, cipherText);
+ cryptoUtil.DecryptString(cipherText, plainText);
+ MgUtil::MultiByteToWideChar(plainText, decryptedPartialConnString);
+
+ MG_CRYPTOGRAPHY_CATCH(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues")
+
+ if (cryptographyException != NULL)
+ {
+ decryptedPartialConnString = partialConnString;
+ }
+ }
+
+ // ODBC provider returns list of DataSourceNames and does not require connection string for this.
+ // Therefore, limitation on connection string to be valid is removed. Also, as ODBC provider does
+ // provide any connection string, connection can not be opened and it will remain in closed state.
+ // Therefore validity of connection state does not apply.
+
+ // Connect to provider
+ Ptr<MgFeatureConnection> msfc = new MgFeatureConnection(providerName, decryptedPartialConnString);
+ {
+ if(NULL == msfc.p)
+ {
+ throw new MgConnectionFailedException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+ // otherwise it leaves the FDO connection marked as still in use.
+ FdoPtr<FdoIConnection> fdoConn = msfc->GetConnection();
+ CHECKNULL((FdoIConnection*)fdoConn, L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues");
+
+ // Get Connection Info
+ FdoPtr<FdoIConnectionInfo> connInfo = fdoConn->GetConnectionInfo();
+ CHECKNULL((FdoIConnectionInfo*)connInfo, L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues");
+
+ // Get Connection Property Dictionary
+ FdoPtr<FdoIConnectionPropertyDictionary> fdoConnPropDict = connInfo->GetConnectionProperties();
+ CHECKNULL((FdoIConnectionPropertyDictionary*)fdoConnPropDict, L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues");
+
+ bool enumerable = fdoConnPropDict->IsPropertyEnumerable((FdoString*)propertyName.c_str());
+ if (!enumerable)
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"2");
+ arguments.Add(propertyName);
+
+ throw new MgInvalidArgumentException(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues",
+ __LINE__, __WFILE__, &arguments, L"MgPropertyNotEnumerable", NULL);
+ }
+
+ FdoInt32 cnt = 0;
+ FdoString** propertyValues = fdoConnPropDict->EnumeratePropertyValues((FdoString*)propertyName.c_str(), cnt);
+
+ if (propertyValues != NULL && cnt > 0)
+ {
+ stringCol = new MgStringCollection();
+ for( FdoInt32 i=0; i < cnt; i++ )
+ {
+ stringCol->Add(propertyValues[i]);
+ }
+ }
+ }
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetConnectionPropertyValues.GetConnectionPropertyValues")
+
+ return stringCol.Detach();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetConnectionPropertyValues.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_GETCONNECTIONPROPERTYVALUES_H_
+#define _MG_SERVER_GETCONNECTIONPROPERTYVALUES_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgServerGetConnectionPropertyValues
+{
+public:
+ MgServerGetConnectionPropertyValues();
+ ~MgServerGetConnectionPropertyValues();
+ MgStringCollection* GetConnectionPropertyValues( CREFSTRING providerName,
+ CREFSTRING propertyName,
+ CREFSTRING partialConnString );
+
+private:
+ STRING m_providerName;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,217 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "GetFeatureProviders.h"
+
+MgServerGetFeatureProviders::MgServerGetFeatureProviders()
+{
+ FdoPtr<IProviderRegistry> providerReg = FdoFeatureAccessManager::GetProviderRegistry();
+ CHECKNULL(providerReg, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+
+ FdoPtr<IConnectionManager> connManager = FdoFeatureAccessManager::GetConnectionManager();
+ CHECKNULL(connManager, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+
+ m_fdoProviderCol = providerReg->GetProviders();
+ CHECKNULL(m_fdoProviderCol, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+
+ // this XML follows the FeatureProviderRegistry-1.0.0.xsd schema
+ m_xmlUtil = new MgXmlUtil("FeatureProviderRegistry" /* NOXLATE */);
+ CHECKNULL(m_xmlUtil, L"MgServerGetFeatureProviders.MgServerGetFeatureProviders()");
+
+ // no more risk of exceptions, so we can now assign these
+ m_providerReg = providerReg.Detach();
+ m_connManager = connManager.Detach();
+}
+
+MgServerGetFeatureProviders::~MgServerGetFeatureProviders()
+{
+ FDO_SAFE_RELEASE(m_providerReg);
+ FDO_SAFE_RELEASE(m_connManager);
+
+ // do not release this one
+ m_fdoProviderCol = NULL;
+
+ delete m_xmlUtil;
+}
+
+
+MgByteReader* MgServerGetFeatureProviders::GetFeatureProviders()
+{
+ Ptr<MgByteReader> byteReader;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ CreateFeatureProvidersDocument();
+ byteReader = m_xmlUtil->ToReader();
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetFeatureProviders.GetFeatureProviders")
+
+ return byteReader.Detach();
+}
+
+void MgServerGetFeatureProviders::CreateFeatureProvidersDocument()
+{
+ CHECKNULL(m_fdoProviderCol, L"MgServerGetFeatureProviders.CreateFeatureProvidersDocument");
+
+ INT32 cnt = m_fdoProviderCol->GetCount();
+ for (INT32 i = 0; i < cnt; i++)
+ {
+ FdoPtr<FdoProvider> fdoProvider = m_fdoProviderCol->GetItem(i);
+
+ // Get ProviderName
+ FdoString* providerName = fdoProvider->GetName();
+
+ const char *name = MgUtil::WideCharToMultiByte(providerName);
+ const char *dispname = MgUtil::WideCharToMultiByte(fdoProvider->GetDisplayName());
+ const char *description = MgUtil::WideCharToMultiByte(fdoProvider->GetDescription());
+ const char *version = MgUtil::WideCharToMultiByte(fdoProvider->GetVersion());
+ const char *fdoversion = MgUtil::WideCharToMultiByte(fdoProvider->GetFeatureDataObjectsVersion());
+
+ // Add Feature Provider element
+ DOMElement* rootElem = m_xmlUtil->GetRootNode();
+ DOMElement* featureProviderElem = m_xmlUtil->AddChildNode(rootElem, "FeatureProvider" /* NOXLATE */);
+
+ // Add Provider Name
+ m_xmlUtil->AddTextNode(featureProviderElem, "Name" /* NOXLATE */, name);
+ // Display Name
+ m_xmlUtil->AddTextNode(featureProviderElem, "DisplayName" /* NOXLATE */, dispname);
+ // Description
+ m_xmlUtil->AddTextNode(featureProviderElem, "Description" /* NOXLATE */, description);
+ // Version
+ m_xmlUtil->AddTextNode(featureProviderElem, "Version" /* NOXLATE */, version);
+ // FDO version
+ m_xmlUtil->AddTextNode(featureProviderElem, "FeatureDataObjectsVersion" /* NOXLATE */, fdoversion);
+
+ delete[] name;
+ delete[] dispname;
+ delete[] description;
+ delete[] version;
+ delete[] fdoversion;
+
+ AddConnectionProperties(featureProviderElem, providerName);
+ }
+}
+
+void MgServerGetFeatureProviders::AddConnectionProperties(DOMElement* providerElem, FdoString* providerName)
+{
+ CHECKNULL(providerElem, L"MgServerGetFeatureProviders.AddConnectionProperties");
+
+ // Get Properties
+ FdoInt32 totalProperties = 0;
+
+ // Add ConnnectionProperties element (mandatory element)
+ DOMElement* connPropRootElem = m_xmlUtil->AddChildNode(providerElem, "ConnectionProperties" /* NOXLATE */ );
+ CHECKNULL(connPropRootElem, L"MgServerGetFeatureProviders.AddConnectionProperties");
+
+ // We ignore any exception thrown here so that even if client dll/so is missing, GetFeatureProviders
+ // will continue to work.
+ MG_FEATURE_SERVICE_TRY()
+
+ // Get FdoIConnection instance
+ // TODO: Should this connection be cached?
+ FdoPtr<FdoIConnection> fdoConn = m_connManager->CreateConnection(providerName);
+ CHECKNULL((FdoIConnection*)fdoConn, L"MgServerGetFeatureProviders.AddConnectionProperties");
+
+ // Get FdoIConnectionInfo
+ FdoPtr<FdoIConnectionInfo> fdoConnInfo = fdoConn->GetConnectionInfo();
+ CHECKNULL((FdoIConnectionInfo*)fdoConnInfo, L"MgServerGetFeatureProviders.AddConnectionProperties");
+
+ // Get FdoIConnectionPropertyDictionary
+ FdoPtr<FdoIConnectionPropertyDictionary> fdoConnPropertyDict = fdoConnInfo->GetConnectionProperties();
+ CHECKNULL((FdoIConnectionPropertyDictionary*)fdoConnPropertyDict, L"MgServerGetFeatureProviders.AddConnectionProperties");
+
+ // Get list of all properties
+ FdoString** properties = fdoConnPropertyDict->GetPropertyNames(totalProperties);
+ CHECKNULL(properties, L"MgServerGetFeatureProviders.AddConnectionProperties");
+
+ for ( FdoInt32 i=0; i < totalProperties; i++ )
+ {
+ AddConnectionProperty(connPropRootElem, properties[i], fdoConnPropertyDict);
+ }
+
+ MG_FEATURE_SERVICE_CATCH(L"MgServerGetFeatureProviders.GetFeatureProviders") // do not rethrow so that GetFeatureProviders works
+}
+
+void MgServerGetFeatureProviders::AddConnectionProperty(DOMElement* connPropRootElem,
+ FdoString* propertyName,
+ FdoIConnectionPropertyDictionary* fdoConnPropertyDict)
+{
+ CHECKNULL(connPropRootElem, L"MgServerGetFeatureProviders.AddConnectionProperty");
+ CHECKNULL(propertyName, L"MgServerGetFeatureProviders.AddConnectionProperty");
+ CHECKNULL(fdoConnPropertyDict, L"MgServerGetFeatureProviders.AddConnectionProperty");
+
+ DOMElement* connPropElem = m_xmlUtil->AddChildNode(connPropRootElem, "ConnectionProperty" /* NOXLATE */ );
+
+ bool isEnumerable = fdoConnPropertyDict->IsPropertyEnumerable(propertyName);
+ bool isProtected = fdoConnPropertyDict->IsPropertyProtected(propertyName);
+ bool isRequired = fdoConnPropertyDict->IsPropertyRequired(propertyName);
+
+ // Set Required attribute
+ if (isRequired)
+ connPropElem->setAttribute(X("Required"), X("true") /* NOXLATE */);
+ else
+ connPropElem->setAttribute(X("Required"), X("false") /* NOXLATE */);
+
+ // Set protected attribute
+ if (isProtected)
+ connPropElem->setAttribute(X("Protected"), X("true") /* NOXLATE */);
+ else
+ connPropElem->setAttribute(X("Protected"), X("false") /* NOXLATE */);
+
+ // Set enumerable attribute
+ if (isEnumerable)
+ connPropElem->setAttribute(X("Enumerable"), X("true") /* NOXLATE */);
+ else
+ connPropElem->setAttribute(X("Enumerable"), X("false") /* NOXLATE */);
+
+ // Add property name
+ const char *propName = MgUtil::WideCharToMultiByte(propertyName);
+ m_xmlUtil->AddTextNode(connPropElem, "Name" /* NOXLATE */, propName);
+ delete[] propName;
+
+ // Add Localized Name
+ FdoString* propLocalizedName = fdoConnPropertyDict->GetLocalizedName(propertyName);
+ if (propLocalizedName)
+ {
+ const char *localname = MgUtil::WideCharToMultiByte(propLocalizedName);
+ m_xmlUtil->AddTextNode(connPropElem, "LocalizedName" /* NOXLATE */, localname);
+ delete[] localname;
+ }
+
+ // Add Default value
+ FdoString* propDefaultValue = fdoConnPropertyDict->GetPropertyDefault(propertyName);
+ if (propDefaultValue)
+ {
+ const char *defvalue = MgUtil::WideCharToMultiByte(propDefaultValue);
+ m_xmlUtil->AddTextNode(connPropElem, "DefaultValue" /* NOXLATE */, defvalue);
+ delete[] defvalue;
+ }
+
+ // Add the values of enumerable properties if we can
+ if (isEnumerable)
+ {
+ FdoInt32 propCnt;
+ FdoString** propValues = fdoConnPropertyDict->EnumeratePropertyValues(propertyName, propCnt);
+ for ( FdoInt32 j = 0; j < propCnt; j++ )
+ {
+ const char *value = MgUtil::WideCharToMultiByte(propValues[j]);
+ m_xmlUtil->AddTextNode(connPropElem, "Value" /* NOXLATE */, value);
+ delete[] value;
+ }
+ }
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetFeatureProviders.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_GET_FEATURE_PROVIDERS_H_
+#define _MG_SERVER_GET_FEATURE_PROVIDERS_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgServerGetFeatureProviders
+{
+public:
+ MgServerGetFeatureProviders();
+ ~MgServerGetFeatureProviders();
+
+
+ MgByteReader* GetFeatureProviders();
+
+private:
+
+ void CreateFeatureProvidersDocument();
+
+ void AddConnectionProperties( DOMElement* providerElem,
+ FdoString* providerName);
+
+ void AddConnectionProperty( DOMElement* connPropRootElem,
+ FdoString* propertyName,
+ FdoIConnectionPropertyDictionary* fdoConnPropertyDict);
+
+ IProviderRegistry* m_providerReg;
+ IConnectionManager* m_connManager;
+ MgXmlUtil* m_xmlUtil;
+
+ const FdoProviderCollection* m_fdoProviderCol;
+
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,157 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "GetLongTransactions.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FeatureUtil.h"
+#include <math.h>
+
+MgServerGetLongTransactions::MgServerGetLongTransactions()
+{
+}
+
+MgServerGetLongTransactions::~MgServerGetLongTransactions()
+{
+}
+
+// Executes the get long transactions command and serializes the schema to XML
+MgLongTransactionReader* MgServerGetLongTransactions::GetLongTransactions(MgResourceIdentifier* resId, bool bActiveOnly)
+{
+ Ptr<MgLongTransactionReader> mgLongTransactionReader;
+ mgLongTransactionReader = NULL;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ if (NULL == resId)
+ {
+ throw new MgNullArgumentException(L"MgServerGetLongTransactions.GetLongTransactions", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ // Connect to provider
+ Ptr<MgFeatureConnection> msfc = new MgFeatureConnection(resId);
+
+ // connection must be open to retrieve list of active contexts
+ if ((NULL != msfc.p) && ( msfc->IsConnectionOpen() ))
+ {
+ // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+ // otherwise it leaves the FDO connection marked as still in use.
+ FdoPtr<FdoIConnection> fdoConn = msfc->GetConnection();
+ m_providerName = msfc->GetProviderName();
+
+ // Check whether command is supported by provider
+ if (!msfc->SupportsCommand((INT32)FdoCommandType_GetLongTransactions))
+ {
+ // TODO: specify which argument and message, once we have the mechanism
+ STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
+ throw new MgInvalidOperationException(L"MgServerGetLongTransactions.GetLongTransactions", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ FdoPtr<FdoIGetLongTransactions> fdoCommand = (FdoIGetLongTransactions*)fdoConn->CreateCommand(FdoCommandType_GetLongTransactions);
+ CHECKNULL((FdoIGetLongTransactions*)fdoCommand, L"MgServerGetLongTransactions.GetLongTransactions");
+
+ // Execute the command
+ FdoPtr<FdoILongTransactionReader> longTransactionReader = fdoCommand->Execute();
+ CHECKNULL((FdoILongTransactionReader*)longTransactionReader, L"MgServerGetLongTransactions.GetLongTransactions");
+
+ mgLongTransactionReader = new MgLongTransactionReader();
+ while (longTransactionReader->ReadNext())
+ {
+ // If only active long transaction is required skip all others
+ if (bActiveOnly)
+ {
+ if (!longTransactionReader->IsActive())
+ continue;
+ }
+
+ // Set providername for which long transaction reader is executed
+ mgLongTransactionReader->SetProviderName(m_providerName);
+
+ // Add transaction data to the long transaction reader
+ Ptr<MgLongTransactionData> longTransactionData = GetLongTransactionData(longTransactionReader);
+ CHECKNULL((MgLongTransactionData*)longTransactionData, L"MgServerGetLongTransactions.GetLongTransactions");
+ mgLongTransactionReader->AddLongTransactionData(longTransactionData);
+
+ // If only active long transaction is required skip all others
+ if (bActiveOnly)
+ {
+ if (longTransactionReader->IsActive())
+ break;
+ }
+ }
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgServerGetLongTransactions::GetLongTransactions()", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resId, L"MgServerGetLongTransactions.GetLongTransactions")
+
+ return mgLongTransactionReader.Detach();
+}
+
+MgLongTransactionData* MgServerGetLongTransactions::GetLongTransactionData(FdoILongTransactionReader* longTransactionReader)
+{
+ Ptr<MgLongTransactionData> longTransactionData = new MgLongTransactionData();
+
+ // Name must exist
+ FdoString* name = longTransactionReader->GetName();
+ CHECKNULL((FdoString*)name, L"MgServerGetLongTransactions.GetLongTransactions");
+ longTransactionData->SetName(STRING(name));
+
+ // Desc for long transaction
+ FdoString* desc = longTransactionReader->GetDescription();
+ if (desc != NULL)
+ {
+ longTransactionData->SetDescription(STRING(desc));
+ }
+
+ // Owner for long transaction
+ FdoString* owner = longTransactionReader->GetOwner();
+ if (owner != NULL)
+ {
+ longTransactionData->SetOwner(STRING(owner));
+ }
+
+ // Creation date
+ Ptr<MgDateTime> mgDateTime;
+
+ FdoDateTime dateTime = longTransactionReader->GetCreationDate();
+ if(dateTime.IsDateTime())
+ {
+ // Valid datetime
+ double seconds;
+ double microsecs = modf(dateTime.seconds, &seconds);
+
+ mgDateTime = new MgDateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute, (INT8)(int)seconds, (INT32)microsecs);
+ }
+ else
+ {
+ // Invalid datetime, so use current date
+ mgDateTime = new MgDateTime();
+ }
+
+ // Whether it is active or not
+ bool isActive = longTransactionReader->IsActive();
+ longTransactionData->SetActiveStatus(isActive);
+
+ // Whether it is frozen or not
+ bool isFrozen = longTransactionReader->IsFrozen();
+ longTransactionData->SetFrozenStatus(isFrozen);
+
+ return longTransactionData.Detach();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetLongTransactions.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVERGETLONGTRANSACTIONS_H_
+#define _MG_SERVERGETLONGTRANSACTIONS_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgServerGetLongTransactions
+{
+public:
+ MgServerGetLongTransactions();
+ ~MgServerGetLongTransactions();
+ MgLongTransactionReader* GetLongTransactions(MgResourceIdentifier* resId, bool bActiveOnly);
+ MgLongTransactionData* GetLongTransactionData(FdoILongTransactionReader* longTransactionReader);
+
+private:
+ STRING m_providerName;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,1036 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "GetProviderCapabilities.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FeatureUtil.h"
+
+/*
+static std::map<FdoThreadCapability, std::string> s_FdoThreadCapability;
+static std::map<FdoSpatialContextExtentType, std::string> s_FdoSpatialContextExtentType;
+static std::map<FdoClassType, std::string> s_FdoClassType;
+static std::map<FdoDataType, std::string> s_FdoDataType;
+static std::map<FdoPropertyType, std::string> s_FdoPropertyTypeAsString;
+static std::map<FdoFunctionCategoryType, std::string> s_FdoFunctionCategoryType;
+static std::map<FdoCommandType, std::string> s_FdoCommandType;
+static std::map<FdoConditionType, std::string> s_FdoConditionType;
+static std::map<FdoSpatialOperations, std::string> s_FdoSpatialOperations;
+static std::map<FdoDistanceOperations, std::string> s_FdoDistanceOperations;
+static std::map<FdoExpressionType, std::string> s_FdoExpressionType;
+static std::map<FdoGeometryType, std::string> s_FdoGeometryType;
+static std::map<FdoGeometryComponentType, std::string> s_FdoGeometryComponentType;
+*/
+
+bool MgServerGetProviderCapabilities::m_isInitialized = MgServerGetProviderCapabilities::Initialize();
+
+
+MgServerGetProviderCapabilities::MgServerGetProviderCapabilities(CREFSTRING providerName, CREFSTRING connectionString)
+{
+ if (providerName.empty())
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"1");
+ arguments.Add(MgResources::BlankArgument);
+
+ throw new MgInvalidArgumentException(L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities",
+ __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
+ }
+
+ FdoPtr<IConnectionManager> connManager = FdoFeatureAccessManager::GetConnectionManager();
+ CHECKNULL(connManager, L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities");
+
+ // Remove the version from the provider name
+ FdoPtr<FdoProviderNameTokens> tokens = FdoProviderNameTokens::Create(providerName.c_str());
+ FdoStringsP strTokens = tokens->GetNameTokens();
+
+ FdoPtr<FdoStringElement> companyName = strTokens->GetItem(0);
+ FdoPtr<FdoStringElement> prvName = strTokens->GetItem(1);
+
+ STRING providerNoVersion;
+ providerNoVersion = companyName->GetString();
+ providerNoVersion += L".";
+ providerNoVersion += prvName->GetString();
+
+ FdoPtr<FdoIConnection> fdoConn = connManager->CreateConnection(providerNoVersion.c_str());
+
+ // Note: WFS doesn't return the proper capabilities if a connection is not opened to the actual server using a connection string.
+
+ // Check if a connection string was specified
+ if(!connectionString.empty())
+ {
+ fdoConn->SetConnectionString(connectionString.c_str());
+ fdoConn->Open();
+ }
+
+ CHECKNULL(fdoConn, L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities");
+
+ m_xmlUtil = new MgXmlUtil();
+ CHECKNULL(m_xmlUtil, L"MgServerGetProviderCapabilities.MgServerGetProviderCapabilities");
+
+ m_xmlCap = NULL;
+
+ // no more risk of exceptions, so we can now assign these
+ m_fdoConn = fdoConn.Detach();
+ m_providerName = providerNoVersion;
+}
+
+MgServerGetProviderCapabilities::~MgServerGetProviderCapabilities()
+{
+ // Check if the connection needs to be closed
+ if(m_fdoConn->GetConnectionState() == FdoConnectionState_Open)
+ {
+ m_fdoConn->Close();
+ }
+
+ m_fdoConn = NULL;
+
+ delete m_xmlUtil;
+ delete m_xmlCap;
+}
+
+
+MgByteReader* MgServerGetProviderCapabilities::GetProviderCapabilities()
+{
+ CHECKNULL(m_xmlUtil, L"MgServerGetProviderCapabilities.GetProviderCapabilities");
+ Ptr<MgByteReader> byteReader;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ // Generate the capability document
+ CreateCapabilitiesDocument();
+
+ if (m_xmlCap != NULL)
+ {
+ byteReader = m_xmlCap->ToReader();
+ }
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetProviderCapabilities.GetProviderCapabilities")
+
+ return byteReader.Detach();
+}
+
+void MgServerGetProviderCapabilities::CreateCapabilitiesDocument()
+{
+ // Root node element created
+ // this XML follows the FdoProviderCapabilities-1.0.0.xsd schema
+ m_xmlCap = new MgXmlUtil("FeatureProviderCapabilities");
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateCapabilitiesDocument");
+ DOMElement* root = m_xmlCap->GetRootNode();
+
+ // Provide name element and its attribute
+ DOMElement* providerNode = m_xmlCap->AddChildNode(root, "Provider");
+ m_xmlCap->SetAttribute(providerNode, "Name", m_providerName.c_str());
+
+ // Connection capabilities
+ CreateConnectionCapabilities();
+
+ CreateSchemaCapabilities();
+ CreateCommandCapabilities();
+ CreateFilterCapabilities();
+ //if (m_version == VERSION_SUPPORTED(1,0))
+ // CreateExpressionCapabilities();
+ //else
+ CreateExpressionCapabilities2();
+ CreateRasterCapabilities();
+ CreateTopologyCapabilities();
+ CreateGeometryCapabilities();
+}
+
+
+
+void MgServerGetProviderCapabilities::CreateConnectionCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+
+ DOMElement* connNode = m_xmlCap->AddChildNode(root, "Connection");
+ CHECKNULL(connNode, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+
+ FdoPtr<FdoIConnectionCapabilities> ficc = m_fdoConn->GetConnectionCapabilities();
+ CHECKNULL((FdoIConnectionCapabilities*)ficc, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+
+ // Thread
+ FdoThreadCapability ftc = ficc->GetThreadCapability();
+ string str = s_FdoThreadCapability[ftc];
+ m_xmlCap->AddTextNode(connNode, "ThreadCapability", str.c_str());
+
+ // Spatial Context
+ FdoInt32 cnt;
+ FdoSpatialContextExtentType* fscet = ficc->GetSpatialContextTypes(cnt);
+ if (cnt > 0 && fscet != NULL)
+ {
+ DOMElement* scNode = m_xmlCap->AddChildNode(connNode, "SpatialContextExtent");
+ CHECKNULL(scNode, L"MgServerGetProviderCapabilities::CreateConnectionCapabilities");
+
+ for (FdoInt32 i = 0; i < cnt; i++)
+ {
+ string scStr = s_FdoSpatialContextExtentType[fscet[i]];
+ m_xmlCap->AddTextNode(scNode, "Type", scStr.c_str());
+ }
+ }
+
+ // Locking
+ bool supportsLocking = ficc->SupportsLocking();
+ m_xmlCap->AddTextNode(connNode, "SupportsLocking", supportsLocking);
+
+ bool supportsTimeout = ficc->SupportsTimeout();
+ m_xmlCap->AddTextNode(connNode, "SupportsTimeout", supportsTimeout);
+
+ bool supportsTransactions = ficc->SupportsTransactions();
+ m_xmlCap->AddTextNode(connNode, "SupportsTransactions", supportsTransactions);
+
+ bool supportsSavePoint = ficc->SupportsSavePoint();
+ m_xmlCap->AddTextNode(connNode, "SupportsSavePoint", supportsSavePoint);
+
+ bool supportsLongTransactions = ficc->SupportsLongTransactions();
+ m_xmlCap->AddTextNode(connNode, "SupportsLongTransactions", supportsLongTransactions);
+
+ bool supportsSQL = ficc->SupportsSQL();
+ m_xmlCap->AddTextNode(connNode, "SupportsSQL", supportsSQL);
+
+ bool supportsConfiguration = ficc->SupportsConfiguration();
+ m_xmlCap->AddTextNode(connNode, "SupportsConfiguration", supportsConfiguration);
+}
+
+
+void MgServerGetProviderCapabilities::CreateSchemaCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+
+ FdoPtr<FdoISchemaCapabilities> fsc = m_fdoConn->GetSchemaCapabilities();
+ CHECKNULL((FdoISchemaCapabilities*)fsc, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+
+ DOMElement* schemaNode = m_xmlCap->AddChildNode(root, "Schema");
+ CHECKNULL(schemaNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+
+ // Add all class types
+ FdoInt32 cnt = 0;
+ FdoClassType* fct = fsc->GetClassTypes(cnt);
+ if (cnt > 0 && fct != NULL)
+ {
+ DOMElement* classNode = m_xmlCap->AddChildNode(schemaNode, "Class");
+ CHECKNULL(classNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string scStr = s_FdoClassType[fct[i]];
+ m_xmlCap->AddTextNode(classNode, "Type", scStr.c_str());
+ }
+ }
+
+ // Add all data types
+ cnt = 0;
+ FdoDataType* fdt = fsc->GetDataTypes(cnt);
+ if (cnt > 0 && fdt != NULL)
+ {
+ DOMElement* dataNode = m_xmlCap->AddChildNode(schemaNode, "Data");
+ CHECKNULL(dataNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string dtStr = s_FdoDataType[fdt[i]];
+ m_xmlCap->AddTextNode(dataNode, "Type", dtStr.c_str());
+ }
+ }
+
+ // Supports Inheritance
+ bool supportsInheritance = fsc->SupportsInheritance();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsInheritance", supportsInheritance);
+
+ // Supports Multiple Schemas
+ bool supportsMultipleSchemas = fsc->SupportsMultipleSchemas();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsMultipleSchemas", supportsMultipleSchemas);
+
+ bool supportsObjectProperties = fsc->SupportsObjectProperties();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsObjectProperties", supportsObjectProperties);
+
+ bool supportsAssociationProperties = fsc->SupportsAssociationProperties();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsAssociationProperties", supportsAssociationProperties);
+
+ bool supportsSchemaOverrides = fsc->SupportsSchemaOverrides();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsSchemaOverrides", supportsSchemaOverrides);
+
+ bool supportsNetworkModel = fsc->SupportsNetworkModel();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsNetworkModel", supportsNetworkModel);
+
+ bool supportsAutoIdGeneration = fsc->SupportsAutoIdGeneration();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsAutoIdGeneration", supportsAutoIdGeneration);
+
+ bool supportsDataStoreScopeUniqueIdGeneration = fsc->SupportsDataStoreScopeUniqueIdGeneration();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsDataStoreScopeUniqueIdGeneration", supportsDataStoreScopeUniqueIdGeneration);
+
+ FdoDataType* sagt = fsc->GetSupportedAutoGeneratedTypes(cnt);
+ if (cnt > 0 && sagt != NULL)
+ {
+ DOMElement* sagtNode = m_xmlCap->AddChildNode(schemaNode, "SupportedAutoGeneratedTypes");
+ CHECKNULL(sagtNode, L"MgServerGetProviderCapabilities::CreateSchemaCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string sagtStr = s_FdoDataType[sagt[i]];
+ m_xmlCap->AddTextNode(sagtNode, "Type", sagtStr.c_str());
+ }
+ }
+
+ bool supportsSchemaModification = fsc->SupportsSchemaModification();
+ m_xmlCap->AddTextNode(schemaNode, "SupportsSchemaModification", supportsSchemaModification);
+}
+
+void MgServerGetProviderCapabilities::CreateCommandCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+
+ FdoPtr<FdoICommandCapabilities> fcc = m_fdoConn->GetCommandCapabilities();
+ CHECKNULL((FdoICommandCapabilities*)fcc, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+
+ DOMElement* cmdNode = m_xmlCap->AddChildNode(root, "Command");
+ CHECKNULL(cmdNode, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+
+ // Add all command types
+ FdoInt32 cnt = 0;
+ FdoInt32* fcmd = fcc->GetCommands(cnt);
+ if (cnt > 0 && fcmd != NULL)
+ {
+ DOMElement* scNode = m_xmlCap->AddChildNode(cmdNode, "SupportedCommands");
+ CHECKNULL(scNode, L"MgServerGetProviderCapabilities::CreateCommandCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string cmdStr = s_FdoCommandType[(FdoCommandType)fcmd[i]];
+ if (!cmdStr.empty())
+ {
+ switch (fcmd[i])
+ {
+ case FdoCommandType_DescribeSchemaMapping:
+ case FdoCommandType_NetworkShortestPath:
+ case FdoCommandType_NetworkAllPaths:
+ case FdoCommandType_NetworkReachableNodes:
+ case FdoCommandType_NetworkReachingNodes:
+ case FdoCommandType_NetworkNearestNeighbors:
+ case FdoCommandType_NetworkWithinCost:
+ case FdoCommandType_NetworkTSP:
+ case FdoCommandType_ActivateTopologyArea:
+ case FdoCommandType_DeactivateTopologyArea:
+ case FdoCommandType_ActivateTopologyInCommandResult:
+ case FdoCommandType_DeactivateTopologyInCommandResults:
+ case FdoCommandType_SelectAggregates:
+ case FdoCommandType_CreateDataStore:
+ case FdoCommandType_DestroyDataStore:
+ case FdoCommandType_ListDataStores:
+ //if (m_version == VERSION_SUPPORTED(1,0))
+ break;
+ // these enumerates were added for version 2
+ // fall thru to write this command
+ default:
+ m_xmlCap->AddTextNode(scNode, "Name", cmdStr.c_str());
+ break;
+ }
+ }
+ }
+ }
+
+ // Supports Parameters
+ bool supportsParameters = fcc->SupportsParameters();
+ m_xmlCap->AddTextNode(cmdNode, "SupportsParameters", supportsParameters);
+
+ // Supports Timeout
+ bool supportsTimeout = fcc->SupportsTimeout();
+ m_xmlCap->AddTextNode(cmdNode, "SupportsTimeout", supportsTimeout);
+
+ // Supports SupportsSelectExpressions
+ bool supportsSelectExpressions = fcc->SupportsSelectExpressions();
+ m_xmlCap->AddTextNode(cmdNode, "SupportsSelectExpressions", supportsSelectExpressions);
+
+ // Supports SupportsSelectFunctions
+ bool supportsSelectFunctions = fcc->SupportsSelectFunctions();
+ m_xmlCap->AddTextNode(cmdNode, "SupportsSelectFunctions", supportsSelectFunctions);
+
+ // Supports SupportsSelectDistinct
+ bool supportsSelectDistinct = fcc->SupportsSelectDistinct();
+ m_xmlCap->AddTextNode(cmdNode, "SupportsSelectDistinct", supportsSelectDistinct);
+
+ // Supports SupportsSelectOrdering
+ bool supportsSelectOrdering = fcc->SupportsSelectOrdering();
+ m_xmlCap->AddTextNode(cmdNode, "SupportsSelectOrdering", supportsSelectOrdering);
+
+ // Supports SupportsSelectGrouping
+ bool supportsSelectGrouping = fcc->SupportsSelectGrouping();
+ m_xmlCap->AddTextNode(cmdNode, "SupportsSelectGrouping", supportsSelectGrouping);
+}
+
+void MgServerGetProviderCapabilities::CreateFilterCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+
+ FdoPtr<FdoIFilterCapabilities> ffc = m_fdoConn->GetFilterCapabilities();
+ CHECKNULL((FdoIFilterCapabilities*)ffc, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+
+ DOMElement* filterNode = m_xmlCap->AddChildNode(root, "Filter");
+ CHECKNULL(filterNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+
+ // Add all condition types
+ FdoInt32 cnt = 0;
+ FdoConditionType* fct = ffc->GetConditionTypes(cnt);
+ if (cnt > 0 && fct != NULL)
+ {
+ DOMElement* condNode = m_xmlCap->AddChildNode(filterNode, "Condition");
+ CHECKNULL(condNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string condStr = s_FdoConditionType[fct[i]];
+ m_xmlCap->AddTextNode(condNode, "Type", condStr.c_str());
+ }
+ }
+
+ // All spatial operations
+ cnt = 0;
+ FdoSpatialOperations* fso = ffc->GetSpatialOperations(cnt);
+ if (cnt > 0 && fso != NULL)
+ {
+ DOMElement* fsoNode = m_xmlCap->AddChildNode(filterNode, "Spatial");
+ CHECKNULL(fsoNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string operStr = s_FdoSpatialOperations[fso[i]];
+ m_xmlCap->AddTextNode(fsoNode, "Operation", operStr.c_str());
+ }
+ }
+
+ // All distance operations
+ cnt = 0;
+ FdoDistanceOperations* fdo = ffc->GetDistanceOperations(cnt);
+ if (cnt > 0 && fdo != NULL)
+ {
+ DOMElement* distNode = m_xmlCap->AddChildNode(filterNode, "Distance");
+ CHECKNULL(distNode, L"MgServerGetProviderCapabilities::CreateFilterCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string fdoStr = s_FdoDistanceOperations[fdo[i]];
+ m_xmlCap->AddTextNode(distNode, "Operation", fdoStr.c_str());
+ }
+ }
+
+ // supports Geodesic Distance
+ bool supportsGeodesicDistance = ffc->SupportsGeodesicDistance();
+ m_xmlCap->AddTextNode(filterNode, "SupportsGeodesicDistance", supportsGeodesicDistance);
+
+ // supports NonLiteral Geometric Operations
+ bool supportsNonLiteralGeometricOperations = ffc->SupportsNonLiteralGeometricOperations();
+ m_xmlCap->AddTextNode(filterNode, "SupportsNonLiteralGeometricOperations", supportsNonLiteralGeometricOperations);
+}
+
+void MgServerGetProviderCapabilities::CreateExpressionCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ FdoPtr<FdoIExpressionCapabilities> fec = m_fdoConn->GetExpressionCapabilities();
+ CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* expressionNode = m_xmlCap->AddChildNode(root, "Expression");
+ CHECKNULL(expressionNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ // Add all expression types
+ FdoInt32 cnt = 0;
+ FdoExpressionType* fet = fec->GetExpressionTypes(cnt);
+ if (cnt > 0 && fet != NULL)
+ {
+ DOMElement* typeNode = m_xmlCap->AddChildNode(expressionNode, "Type");
+ CHECKNULL(typeNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string typeStr = s_FdoExpressionType[fet[i]];
+ m_xmlCap->AddTextNode(typeNode, "Name", typeStr.c_str());
+ }
+ }
+
+ // Add all functions available
+ cnt = 0;
+ FdoPtr<FdoFunctionDefinitionCollection> ffdc = fec->GetFunctions();
+ if (NULL != (FdoFunctionDefinitionCollection*)ffdc)
+ {
+ FdoInt32 funcCnt = ffdc->GetCount();
+ if (funcCnt > 0)
+ {
+ // Add function definition collection element if there are any functions available
+ DOMElement* funcDefColNode = m_xmlCap->AddChildNode(expressionNode, "FunctionDefinitionList");
+ CHECKNULL(funcDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ for (FdoInt32 i=0; i < funcCnt; i++)
+ {
+ // Add function definition element
+ FdoPtr<FdoFunctionDefinition> ffd = ffdc->GetItem(i);
+ CHECKNULL((FdoFunctionDefinition*)ffd, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* funcDefNode = m_xmlCap->AddChildNode(funcDefColNode, "FunctionDefinition");
+ CHECKNULL(funcDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ const char* strName = MgUtil::WideCharToMultiByte(ffd->GetName());
+ const char* strDesc = MgUtil::WideCharToMultiByte(ffd->GetDescription());
+
+ FdoDataType eDataType = ffd->GetReturnType();
+ string strDataType = s_FdoDataType[eDataType];
+
+ m_xmlCap->AddTextNode(funcDefNode, "Name", strName);
+ m_xmlCap->AddTextNode(funcDefNode, "Description", strDesc);
+ m_xmlCap->AddTextNode(funcDefNode, "ReturnType", strDataType.c_str());
+
+ delete[] strName;
+ delete[] strDesc;
+
+ // Add argument of each functions if there are any
+ FdoPtr<FdoReadOnlyArgumentDefinitionCollection> argCol = ffd->GetArguments();
+ if (NULL != (FdoReadOnlyArgumentDefinitionCollection*)argCol)
+ {
+ FdoInt32 argCnt = argCol->GetCount();
+ if (argCnt > 0)
+ {
+ // Add ArgumentDefinitionCollection if there are arguments
+ DOMElement* argDefColNode = m_xmlCap->AddChildNode(funcDefNode, "ArgumentDefinitionList");
+ CHECKNULL(argDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ for (FdoInt32 j=0; j < argCnt; j++)
+ {
+ // Add ArgumentDefinition for each argument
+ FdoPtr<FdoArgumentDefinition> fad = argCol->GetItem(j);
+ CHECKNULL((FdoArgumentDefinition*)fad, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* argDefNode = m_xmlCap->AddChildNode(argDefColNode, "ArgumentDefinition");
+ CHECKNULL(argDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ const char* strArgName = MgUtil::WideCharToMultiByte(fad->GetName());
+ const char* strArgDesc = MgUtil::WideCharToMultiByte(fad->GetDescription());
+
+ FdoDataType eArgDataType = fad->GetDataType();
+ string strArgDataType = s_FdoDataType[eArgDataType];
+
+ m_xmlCap->AddTextNode(argDefNode, "Name", strArgName);
+ m_xmlCap->AddTextNode(argDefNode, "Description", strArgDesc);
+ m_xmlCap->AddTextNode(argDefNode, "ReturnType", strArgDataType.c_str());
+
+ delete[] strArgName;
+ delete[] strArgDesc;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void MgServerGetProviderCapabilities::CreateExpressionCapabilities2()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ FdoPtr<FdoIExpressionCapabilities> fec = m_fdoConn->GetExpressionCapabilities();
+ CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* expressionNode = m_xmlCap->AddChildNode(root, "Expression");
+ CHECKNULL(expressionNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ // Add all expression types
+ FdoInt32 cnt = 0;
+ FdoExpressionType* fet = fec->GetExpressionTypes(cnt);
+ if (cnt > 0 && fet != NULL)
+ {
+ DOMElement* typeNode = m_xmlCap->AddChildNode(expressionNode, "Type");
+ CHECKNULL(typeNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string typeStr = s_FdoExpressionType[fet[i]];
+ m_xmlCap->AddTextNode(typeNode, "Name", typeStr.c_str());
+ }
+ }
+
+ // Add all functions available
+ cnt = 0;
+ FdoPtr<FdoFunctionDefinitionCollection> ffdc = fec->GetFunctions();
+ if (NULL != (FdoFunctionDefinitionCollection*)ffdc)
+ {
+ FdoInt32 funcCnt = ffdc->GetCount();
+ if (funcCnt > 0)
+ {
+ // Add function definition collection element if there are any functions available
+ DOMElement* funcDefColNode = m_xmlCap->AddChildNode(expressionNode, "FunctionDefinitionList");
+ CHECKNULL(funcDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ for (FdoInt32 i=0; i < funcCnt; i++)
+ {
+ // Add function definition element
+ FdoPtr<FdoFunctionDefinition> ffd = ffdc->GetItem(i);
+ CHECKNULL((FdoFunctionDefinition*)ffd, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* funcDefNode = m_xmlCap->AddChildNode(funcDefColNode, "FunctionDefinition");
+ CHECKNULL(funcDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ const char* strName = MgUtil::WideCharToMultiByte(ffd->GetName());
+ const char* strDesc = MgUtil::WideCharToMultiByte(ffd->GetDescription());
+
+ FdoFunctionCategoryType eFdoFunctionCategoryType = ffd->GetFunctionCategoryType();
+ string strFunctionCategoryType = s_FdoFunctionCategoryType[eFdoFunctionCategoryType];
+
+ m_xmlCap->AddTextNode(funcDefNode, "Name", strName);
+ m_xmlCap->AddTextNode(funcDefNode, "Description", strDesc);
+ m_xmlCap->AddTextNode(funcDefNode, "CategoryType", strFunctionCategoryType.c_str());
+ m_xmlCap->AddTextNode(funcDefNode, "IsAggregate", ffd->IsAggregate());
+ m_xmlCap->AddTextNode(funcDefNode, "IsSupportsVariableArgumentsList", ffd->SupportsVariableArgumentsList());
+
+ delete[] strName;
+ delete[] strDesc;
+
+ // Add argument of each functions if there are any
+ FdoPtr<FdoReadOnlySignatureDefinitionCollection> signatures = ffd->GetSignatures();
+ if (NULL != (FdoReadOnlySignatureDefinitionCollection*)signatures)
+ {
+ FdoInt32 signaturesCnt = signatures->GetCount();
+ if (signaturesCnt > 0)
+ {
+
+ DOMElement* signDefColNode = m_xmlCap->AddChildNode(funcDefNode, "SignatureDefinitionCollection");
+ CHECKNULL(signDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+ for (FdoInt32 j=0; j < signaturesCnt; j++)
+ {
+
+ // Add SignatureDefinition for each signature
+ FdoPtr<FdoSignatureDefinition> fsd = signatures->GetItem(j);
+ CHECKNULL((FdoSignatureDefinition*)fsd, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* signDefNode = m_xmlCap->AddChildNode(signDefColNode, "SignatureDefinition");
+ CHECKNULL(signDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ FdoPropertyType eSignPropertyDataType = fsd->GetReturnPropertyType();
+ string strSignPropertyType = s_FdoPropertyTypeAsString[eSignPropertyDataType];
+ string strSignDataType;
+ if (eSignPropertyDataType == FdoPropertyType_DataProperty)
+ {
+ FdoDataType eSignDataType = fsd->GetReturnType();
+ strSignDataType = s_FdoDataType[eSignDataType];
+ }
+
+ m_xmlCap->AddTextNode(signDefNode, "PropertyType", strSignPropertyType.c_str());
+ if (eSignPropertyDataType == FdoPropertyType_DataProperty)
+ m_xmlCap->AddTextNode(signDefNode, "DataType", strSignDataType.c_str());
+
+ DOMElement* argDefColNode = m_xmlCap->AddChildNode(signDefNode, "ArgumentDefinitionList");
+ CHECKNULL(argDefColNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ FdoPtr<FdoReadOnlyArgumentDefinitionCollection> fads = fsd->GetArguments();
+ if (NULL != (FdoReadOnlyArgumentDefinitionCollection *) fads)
+ {
+ FdoInt32 argCnt = fads->GetCount();
+ if (argCnt > 0)
+ {
+ for (int k=0; k<argCnt; k++)
+ {
+ FdoPtr<FdoArgumentDefinition> fad = fads->GetItem(k);
+ CHECKNULL((FdoArgumentDefinition*)fad, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ DOMElement* argDefNode = m_xmlCap->AddChildNode(argDefColNode, "ArgumentDefinition");
+ CHECKNULL(argDefNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ const char* strArgName = MgUtil::WideCharToMultiByte(fad->GetName());
+ const char* strArgDesc = MgUtil::WideCharToMultiByte(fad->GetDescription());
+
+ FdoPropertyType eArgPropertyDataType = fad->GetPropertyType();
+ string strArgPropertyType = s_FdoPropertyTypeAsString[eArgPropertyDataType];
+ string strArgDataType;
+ if (eArgPropertyDataType == FdoPropertyType_DataProperty)
+ {
+ FdoDataType eArgDataType = fad->GetDataType();
+ strArgDataType = s_FdoDataType[eArgDataType];
+ }
+
+ m_xmlCap->AddTextNode(argDefNode, "Name", strArgName);
+ m_xmlCap->AddTextNode(argDefNode, "Description", strArgDesc);
+ m_xmlCap->AddTextNode(argDefNode, "PropertyType", strArgPropertyType.c_str());
+ if (eArgPropertyDataType == FdoPropertyType_DataProperty)
+ m_xmlCap->AddTextNode(argDefNode, "DataType", strArgDataType.c_str());
+
+ delete[] strArgName;
+ delete[] strArgDesc;
+
+ FdoPtr<FdoPropertyValueConstraintList> fpvc = fad->GetArgumentValueList();
+ if (NULL != (FdoPropertyValueConstraintList *) fpvc)
+ {
+ if (fpvc->GetConstraintType() == FdoPropertyValueConstraintType_List)
+ {
+ DOMElement* propValueConstListNode = m_xmlCap->AddChildNode(argDefNode, "PropertyValueConstraintList");
+ CHECKNULL(propValueConstListNode, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+
+ FdoPropertyValueConstraintType eConstraintType = fpvc->GetConstraintType();
+
+ FdoPtr<FdoDataValueCollection> dvc = fpvc->GetConstraintList();
+ if (NULL != (FdoDataValueCollection *) dvc)
+ {
+ FdoInt32 dvCnt = dvc->GetCount();
+ if (dvCnt > 0)
+ {
+ for (int l=0; l<dvCnt; l++)
+ {
+ FdoPtr<FdoDataValue> dv = dvc->GetItem(l);
+ CHECKNULL((FdoDataValue*)dv, L"MgServerGetProviderCapabilities::CreateExpressionCapabilities");
+ FdoDataType dataType = dv->GetDataType();
+ // FdoDataType_String is the only supported type
+ if (dataType == FdoDataType_String)
+ {
+ FdoStringValue *stringValue = (FdoStringValue *) dv.p;
+ FdoString* xmlValue = stringValue->GetString();
+ const char* strDataValue = MgUtil::WideCharToMultiByte(stringValue->GetString());
+ m_xmlCap->AddTextNode(propValueConstListNode, "Value", xmlValue);
+ delete[] strDataValue;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void MgServerGetProviderCapabilities::CreateRasterCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+
+ FdoPtr<FdoIRasterCapabilities> frc = m_fdoConn->GetRasterCapabilities();
+ CHECKNULL((FdoIRasterCapabilities*)frc, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+
+ DOMElement* rasterNode = m_xmlCap->AddChildNode(root, "Raster");
+ CHECKNULL(rasterNode, L"MgServerGetProviderCapabilities::CreateRasterCapabilities");
+
+ // Supports Raster
+ bool supportsRaster = frc->SupportsRaster();
+ m_xmlCap->AddTextNode(rasterNode, "SupportsRaster", supportsRaster);
+
+ // Supports Stitching
+ bool supportsStitching = frc->SupportsStitching();
+ m_xmlCap->AddTextNode(rasterNode, "SupportsStitching", supportsStitching);
+
+ bool supportsSubsampling = frc->SupportsSubsampling();
+ m_xmlCap->AddTextNode(rasterNode, "SupportsSubsampling", supportsSubsampling);
+
+}
+
+void MgServerGetProviderCapabilities::CreateTopologyCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
+
+ MG_FEATURE_SERVICE_TRY()
+
+ FdoPtr<FdoITopologyCapabilities> frc = m_fdoConn->GetTopologyCapabilities();
+
+ // Provider has no topology capabilities
+ if (NULL == (FdoITopologyCapabilities*)frc)
+ {
+ return;
+ }
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
+
+ DOMElement* topologyNode = m_xmlCap->AddChildNode(root, "Topology");
+ CHECKNULL(topologyNode, L"MgServerGetProviderCapabilities::CreateTopologyCapabilities");
+
+ // Supports Topology
+ bool supportsTopology = frc->SupportsTopology();
+ m_xmlCap->AddTextNode(topologyNode, "SupportsTopology", supportsTopology);
+
+ // Supports Stitching
+ bool supportsTopologicalHierarchy = frc->SupportsTopologicalHierarchy();
+ m_xmlCap->AddTextNode(topologyNode, "SupportsTopologicalHierarchy", supportsTopologicalHierarchy);
+
+ bool breaksCurveCrossingsAutomatically = frc->BreaksCurveCrossingsAutomatically();
+ m_xmlCap->AddTextNode(topologyNode, "BreaksCurveCrossingsAutomatically", breaksCurveCrossingsAutomatically);
+
+ bool activatesTopologyByArea = frc->ActivatesTopologyByArea();
+ m_xmlCap->AddTextNode(topologyNode, "ActivatesTopologyByArea", activatesTopologyByArea);
+
+ bool constrainsFeatureMovements = frc->ConstrainsFeatureMovements();
+ m_xmlCap->AddTextNode(topologyNode, "ConstrainsFeatureMovements", constrainsFeatureMovements);
+
+ // TODO: Change this to CATCH_AND_THROW when SimpleDB stops throwing exception of not implemented
+ MG_FEATURE_SERVICE_CATCH(L"MgServerGetProviderCapabilities.CreateTopologyCapabilities")
+
+}
+
+void MgServerGetProviderCapabilities::CreateGeometryCapabilities()
+{
+ CHECKNULL(m_xmlCap, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+
+ MG_FEATURE_SERVICE_TRY()
+
+ FdoPtr<FdoIGeometryCapabilities> fgc = m_fdoConn->GetGeometryCapabilities();
+
+ // Provider has no geometric capabilities
+ if (NULL == (FdoIGeometryCapabilities*)fgc)
+ {
+ return;
+ }
+
+ DOMElement* root = m_xmlCap->GetRootNode();
+ CHECKNULL(root, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+
+ DOMElement* geometryNode = m_xmlCap->AddChildNode(root, "Geometry");
+ CHECKNULL(geometryNode, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+
+ FdoInt32 cnt = 0;
+ FdoGeometryType* geomType = fgc->GetGeometryTypes(cnt);
+ if (cnt > 0 && geomType != NULL)
+ {
+ DOMElement* geometryTypeNode = m_xmlCap->AddChildNode(geometryNode, "Types");
+ CHECKNULL(geometryTypeNode, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string geomTypeStr = s_FdoGeometryType[geomType[i]];
+ m_xmlCap->AddTextNode(geometryTypeNode, "Type", geomTypeStr.c_str());
+ }
+ }
+
+ FdoGeometryComponentType* geomCompType = fgc->GetGeometryComponentTypes(cnt);
+ if (cnt > 0 && geomCompType != NULL)
+ {
+ DOMElement* geometryCompNode = m_xmlCap->AddChildNode(geometryNode, "Components");
+ CHECKNULL(geometryCompNode, L"MgServerGetProviderCapabilities.CreateGeometryCapabilities");
+
+ for (FdoInt32 i=0; i < cnt; i++)
+ {
+ string geomCompStr = s_FdoGeometryComponentType[geomCompType[i]];
+ m_xmlCap->AddTextNode(geometryCompNode, "Type", geomCompStr.c_str());
+ }
+ }
+
+ FdoInt32 dim = fgc->GetDimensionalities();
+
+ char buff[8]; buff[0] = 0;
+ sprintf(buff, "%d", dim);
+
+ m_xmlCap->AddTextNode(geometryNode, "Dimensionality", &buff[0]);
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetProviderCapabilities.CreateGeometryCapabilities")
+}
+
+bool MgServerGetProviderCapabilities::IsConnectionOpen()
+{
+ CHECKNULL(m_fdoConn, L"MgServerGetProviderCapabilities.IsConnectionOpen");
+
+ FdoConnectionState state = m_fdoConn->GetConnectionState();
+ if (state != FdoConnectionState_Open)
+ return false;
+
+ return true;
+}
+
+bool MgServerGetProviderCapabilities::Initialize()
+{
+ // Thread Capability
+ s_FdoThreadCapability[FdoThreadCapability_SingleThreaded] = "SingleThreaded";
+ s_FdoThreadCapability[FdoThreadCapability_PerConnectionThreaded] = "PerConnectionThreaded";
+ s_FdoThreadCapability[FdoThreadCapability_PerCommandThreaded] = "PerCommandThreaded";
+ s_FdoThreadCapability[FdoThreadCapability_MultiThreaded] = "MultiThreaded";
+
+ // Spatial Extent type
+ s_FdoSpatialContextExtentType[FdoSpatialContextExtentType_Static] = "Static";
+ s_FdoSpatialContextExtentType[FdoSpatialContextExtentType_Dynamic] = "Dynamic";
+
+ // Class Types
+ s_FdoClassType[FdoClassType_Class] = "Class";
+ s_FdoClassType[FdoClassType_FeatureClass] = "FeatureClass";
+ s_FdoClassType[FdoClassType_NetworkClass] = "NetworkClass";
+ s_FdoClassType[FdoClassType_NetworkLayerClass] = "NetworkLayerClass";
+ s_FdoClassType[FdoClassType_NetworkNodeClass] = "NetworkNodeClass";
+
+ // Data types
+ s_FdoDataType[FdoDataType_Boolean] = "Boolean";
+ s_FdoDataType[FdoDataType_Byte] = "Byte";
+ s_FdoDataType[FdoDataType_DateTime] = "DateTime";
+ // Implementation Note: FdoDataType_Decimal is currently mapped to MgPropertyType::Double.
+ // An MgDecimalProperty class should be implemented in a future release.
+ s_FdoDataType[FdoDataType_Decimal] = "Double";
+ s_FdoDataType[FdoDataType_Double] = "Double";
+ s_FdoDataType[FdoDataType_Int16] = "Int16";
+ s_FdoDataType[FdoDataType_Int32] = "Int32";
+ s_FdoDataType[FdoDataType_Int64] = "Int64";
+ s_FdoDataType[FdoDataType_Single] = "Single";
+ s_FdoDataType[FdoDataType_String] = "String";
+ s_FdoDataType[FdoDataType_BLOB] = "BLOB";
+ s_FdoDataType[FdoDataType_CLOB] = "CLOB";
+
+ s_FdoPropertyTypeAsString[FdoPropertyType_DataProperty] = "Data";
+ s_FdoPropertyTypeAsString[FdoPropertyType_GeometricProperty] = "Geometry";
+ s_FdoPropertyTypeAsString[FdoPropertyType_ObjectProperty] = "Object";
+ s_FdoPropertyTypeAsString[FdoPropertyType_AssociationProperty] = "Association";
+ s_FdoPropertyTypeAsString[FdoPropertyType_RasterProperty] = "Raster";
+
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Aggregate] = "Aggregate";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Conversion] = "Conversion";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Custom] = "Custom";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Date] = "Date";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Geometry] = "Geometry";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Math] = "Math";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Numeric] = "Numeric";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_String] = "String";
+ s_FdoFunctionCategoryType[FdoFunctionCategoryType_Unspecified] = "Unspecified";
+
+ // Commands
+ s_FdoCommandType[FdoCommandType_Select] = "Select";
+ s_FdoCommandType[FdoCommandType_Insert] = "Insert";
+ s_FdoCommandType[FdoCommandType_Delete] = "Delete";
+ s_FdoCommandType[FdoCommandType_Update] = "Update";
+ s_FdoCommandType[FdoCommandType_DescribeSchema] = "DescribeSchema";
+ s_FdoCommandType[FdoCommandType_DescribeSchemaMapping] = "DescribeSchemaMapping";
+ s_FdoCommandType[FdoCommandType_ApplySchema] = "ApplySchema";
+ s_FdoCommandType[FdoCommandType_DestroySchema] = "DestroySchema";
+ s_FdoCommandType[FdoCommandType_ActivateSpatialContext] = "ActivateSpatialContext";
+ s_FdoCommandType[FdoCommandType_CreateSpatialContext] = "CreateSpatialContext";
+ s_FdoCommandType[FdoCommandType_DestroySpatialContext] = "DestroySpatialContext";
+ s_FdoCommandType[FdoCommandType_GetSpatialContexts] = "GetSpatialContexts";
+ s_FdoCommandType[FdoCommandType_CreateMeasureUnit] = "CreateMeasureUnit";
+ s_FdoCommandType[FdoCommandType_DestroyMeasureUnit] = "DestroyMeasureUnit";
+ s_FdoCommandType[FdoCommandType_GetMeasureUnits] = "GetMeasureUnits";
+ s_FdoCommandType[FdoCommandType_SQLCommand] = "SQLCommand";
+ s_FdoCommandType[FdoCommandType_AcquireLock] = "AcquireLock";
+ s_FdoCommandType[FdoCommandType_GetLockInfo] = "GetLockInfo";
+ s_FdoCommandType[FdoCommandType_GetLockedObjects] = "GetLockedObjects";
+ s_FdoCommandType[FdoCommandType_GetLockOwners] = "GetLockOwners";
+ s_FdoCommandType[FdoCommandType_ReleaseLock] = "ReleaseLock";
+ s_FdoCommandType[FdoCommandType_ActivateLongTransaction] = "ActivateLongTransaction";
+ s_FdoCommandType[FdoCommandType_DeactivateLongTransaction] = "DeactivateLongTransaction";
+ s_FdoCommandType[FdoCommandType_CommitLongTransaction] = "CommitLongTransaction";
+ s_FdoCommandType[FdoCommandType_CreateLongTransaction] = "CreateLongTransaction";
+ s_FdoCommandType[FdoCommandType_GetLongTransactions] = "GetLongTransactions";
+ s_FdoCommandType[FdoCommandType_FreezeLongTransaction] = "FreezeLongTransaction";
+ s_FdoCommandType[FdoCommandType_RollbackLongTransaction] = "RollbackLongTransaction";
+ s_FdoCommandType[FdoCommandType_ActivateLongTransactionCheckpoint] = "ActivateLongTransactionCheckpoint";
+ s_FdoCommandType[FdoCommandType_CreateLongTransactionCheckpoint] = "CreateLongTransactionCheckpoint";
+ s_FdoCommandType[FdoCommandType_GetLongTransactionCheckpoints] = "GetLongTransactionCheckpoints";
+ s_FdoCommandType[FdoCommandType_RollbackLongTransactionCheckpoint] = "RollbackLongTransactionCheckpoint";
+ s_FdoCommandType[FdoCommandType_ChangeLongTransactionPrivileges] = "ChangeLongTransactionPrivileges";
+ s_FdoCommandType[FdoCommandType_GetLongTransactionPrivileges] = "GetLongTransactionPrivileges";
+ s_FdoCommandType[FdoCommandType_ChangeLongTransactionSet] = "ChangeLongTransactionSet";
+ s_FdoCommandType[FdoCommandType_GetLongTransactionsInSet] = "GetLongTransactionsInSet";
+ s_FdoCommandType[FdoCommandType_NetworkShortestPath] = "NetworkShortestPath";
+ s_FdoCommandType[FdoCommandType_NetworkAllPaths] = "NetworkAllPaths";
+ s_FdoCommandType[FdoCommandType_NetworkReachableNodes] = "NetworkReachableNodes";
+ s_FdoCommandType[FdoCommandType_NetworkReachingNodes] = "NetworkReachingNodes";
+ s_FdoCommandType[FdoCommandType_NetworkNearestNeighbors] = "NetworkNearestNeighbors";
+ s_FdoCommandType[FdoCommandType_NetworkWithinCost] = "NetworkWithinCost";
+ s_FdoCommandType[FdoCommandType_NetworkTSP] = "NetworkTSP";
+ s_FdoCommandType[FdoCommandType_ActivateTopologyArea] = "ActivateTopologyArea";
+ s_FdoCommandType[FdoCommandType_DeactivateTopologyArea] = "DeactivateTopologyArea";
+ s_FdoCommandType[FdoCommandType_ActivateTopologyInCommandResult] = "ActivateTopologyInCommandResult";
+ s_FdoCommandType[FdoCommandType_DeactivateTopologyInCommandResults] = "DeactivateTopologyInCommandResults";
+ s_FdoCommandType[FdoCommandType_SelectAggregates] = "SelectAggregates";
+ s_FdoCommandType[FdoCommandType_CreateDataStore] = "CreateDataStore";
+ s_FdoCommandType[FdoCommandType_DestroyDataStore] = "DestroyDataStore";
+ s_FdoCommandType[FdoCommandType_ListDataStores] = "ListDataStores";
+ s_FdoCommandType[FdoCommandType_FirstProviderCommand] = "FirstProviderCommand";
+
+ // Condition types
+ s_FdoConditionType[FdoConditionType_Comparison] = "Comparison";
+ s_FdoConditionType[FdoConditionType_Like] = "Like";
+ s_FdoConditionType[FdoConditionType_In] = "In";
+ s_FdoConditionType[FdoConditionType_Null] = "Null";
+ s_FdoConditionType[FdoConditionType_Spatial] = "Spatial";
+ s_FdoConditionType[FdoConditionType_Distance] = "Distance";
+
+ // Spatial Operations
+ s_FdoSpatialOperations[FdoSpatialOperations_Contains] = "Contains";
+ s_FdoSpatialOperations[FdoSpatialOperations_Crosses] = "Crosses";
+ s_FdoSpatialOperations[FdoSpatialOperations_Disjoint] = "Disjoint";
+ s_FdoSpatialOperations[FdoSpatialOperations_Equals] = "Equals";
+ s_FdoSpatialOperations[FdoSpatialOperations_Intersects] = "Intersects";
+ s_FdoSpatialOperations[FdoSpatialOperations_Overlaps] = "Overlaps";
+ s_FdoSpatialOperations[FdoSpatialOperations_Touches] = "Touches";
+ s_FdoSpatialOperations[FdoSpatialOperations_Within] = "Within";
+ s_FdoSpatialOperations[FdoSpatialOperations_CoveredBy] = "CoveredBy";
+ s_FdoSpatialOperations[FdoSpatialOperations_Inside] = "Inside";
+ s_FdoSpatialOperations[FdoSpatialOperations_EnvelopeIntersects] = "EnvelopeIntersects";
+
+ // Distance Operation
+ s_FdoDistanceOperations[FdoDistanceOperations_Beyond] = "Beyond";
+ s_FdoDistanceOperations[FdoDistanceOperations_Within] = "Within";
+
+ // Expression Type
+ s_FdoExpressionType[FdoExpressionType_Basic] = "Basic";
+ s_FdoExpressionType[FdoExpressionType_Function] = "Function";
+ s_FdoExpressionType[FdoExpressionType_Parameter] = "Parameter";
+
+ // Geometry Type
+ s_FdoGeometryType[FdoGeometryType_None] = "None";
+ s_FdoGeometryType[FdoGeometryType_Point] = "Point";
+ s_FdoGeometryType[FdoGeometryType_LineString] = "LineString";
+ s_FdoGeometryType[FdoGeometryType_Polygon] = "Polygon";
+ s_FdoGeometryType[FdoGeometryType_MultiPoint] = "MultiPoint";
+ s_FdoGeometryType[FdoGeometryType_MultiLineString] = "MultiLineString";
+ s_FdoGeometryType[FdoGeometryType_MultiPolygon] = "MultiPolygon";
+ s_FdoGeometryType[FdoGeometryType_MultiGeometry] = "MultiGeometry";
+ s_FdoGeometryType[FdoGeometryType_CurveString] = "CurveString";
+ s_FdoGeometryType[FdoGeometryType_CurvePolygon] = "CurvePolygon";
+ s_FdoGeometryType[FdoGeometryType_MultiCurveString] = "MultiCurveString";
+ s_FdoGeometryType[FdoGeometryType_MultiCurvePolygon] = "MultiCurvePolygon";
+
+ // Geometry component type
+ s_FdoGeometryComponentType[FdoGeometryComponentType_LinearRing] = "LinearRing";
+ s_FdoGeometryComponentType[FdoGeometryComponentType_CircularArcSegment] = "ArcSegment";
+ s_FdoGeometryComponentType[FdoGeometryComponentType_LineStringSegment] = "LinearSegment";
+ s_FdoGeometryComponentType[FdoGeometryComponentType_Ring] = "CurveRing";
+
+ return true;
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetProviderCapabilities.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_GET_PROVIDER_CAPABILITIES_H_
+#define _MG_SERVER_GET_PROVIDER_CAPABILITIES_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgServerGetProviderCapabilities
+{
+public:
+ MgServerGetProviderCapabilities(CREFSTRING providerName, CREFSTRING connectionString);
+ ~MgServerGetProviderCapabilities();
+ MgByteReader* GetProviderCapabilities();
+
+private:
+
+ void CreateCapabilitiesDocument();
+ void CreateConnectionCapabilities();
+ void CreateSchemaCapabilities();
+ void CreateCommandCapabilities();
+ void CreateFilterCapabilities();
+ void CreateExpressionCapabilities();
+ void CreateExpressionCapabilities2();
+ void CreateRasterCapabilities();
+ void CreateTopologyCapabilities();
+ void CreateGeometryCapabilities();
+
+ bool IsConnectionOpen();
+ static bool Initialize();
+
+ MgXmlUtil* m_xmlUtil;
+ STRING m_providerName;
+ FdoPtr<FdoIConnection> m_fdoConn;
+ MgXmlUtil* m_xmlCap;
+ static bool m_isInitialized;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,119 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "GetSchemaMapping.h"
+#include "Services/Resource/UnmanagedDataManager.h"
+
+MgServerGetSchemaMapping::MgServerGetSchemaMapping() :
+ m_bytes(NULL)
+{
+}
+
+MgServerGetSchemaMapping::~MgServerGetSchemaMapping()
+{
+ delete [] m_bytes;
+ m_bytes = NULL;
+}
+
+
+MgByteReader* MgServerGetSchemaMapping::GetSchemaMapping(CREFSTRING providerName, CREFSTRING partialConnString)
+{
+ Ptr<MgByteReader> byteReader;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ STRING data = partialConnString;
+ MgUnmanagedDataManager::SubstituteDataPathAliases(data);
+
+ // Connect to the provider
+ Ptr<MgFeatureConnection> msfc = new MgFeatureConnection(providerName, data);
+ if ((NULL != msfc.p) && (( msfc->IsConnectionOpen() ) || ( msfc->IsConnectionPending() )))
+ {
+ // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+ // otherwise it leaves the FDO connection marked as still in use.
+ FdoPtr<FdoIConnection> fdoConnection;
+ fdoConnection = msfc->GetConnection();
+
+ // Create the memory stream
+ FdoIoMemoryStreamP fmis = FdoIoMemoryStream::Create();
+ CHECKNULL((FdoIoMemoryStream*)fmis, L"MgServerGetSchemaMapping.GetSchemaMapping");
+
+ FdoXmlWriterP writer = FdoXmlWriter::Create(fmis);
+
+ FdoPtr<FdoXmlSpatialContextFlags> flags = FdoXmlSpatialContextFlags::Create();
+ flags->SetIncludeDefault(true);
+
+ // Serialize the spatial contexts
+ FdoXmlSpatialContextSerializer::XmlSerialize(
+ fdoConnection,
+ FdoXmlSpatialContextWriterP(
+ FdoXmlSpatialContextWriter::Create(writer)
+ ),
+ flags
+ );
+
+ // Get the schema
+ FdoPtr<FdoIDescribeSchema> fdoDescribeSchemaCommand = (FdoIDescribeSchema*)fdoConnection->CreateCommand(FdoCommandType_DescribeSchema);
+ CHECKNULL((FdoIDescribeSchema*)fdoDescribeSchemaCommand, L"MgServerGetSchemaMapping.GetSchemaMapping");
+
+ // Execute the command
+ FdoPtr<FdoFeatureSchemaCollection> fdoFeatureSchemaCollection;
+ fdoFeatureSchemaCollection = fdoDescribeSchemaCommand->Execute();
+ CHECKNULL((FdoFeatureSchemaCollection*)fdoFeatureSchemaCollection, L"MgServerGetSchemaMapping.GetSchemaMapping");
+
+ // Write to memory stream
+ fdoFeatureSchemaCollection->WriteXml(writer);
+
+ // Get the schema mapping
+ FdoPtr<FdoIDescribeSchemaMapping> fdoDescribeSchemaMappingCommand = (FdoIDescribeSchemaMapping*)fdoConnection->CreateCommand(FdoCommandType_DescribeSchemaMapping);
+ CHECKNULL((FdoIDescribeSchemaMapping*)fdoDescribeSchemaMappingCommand, L"MgServerGetSchemaMapping.GetSchemaMapping");
+
+ fdoDescribeSchemaMappingCommand->SetIncludeDefaults(true);
+
+ // Execute the command
+ FdoPtr<FdoPhysicalSchemaMappingCollection> fdoPhysicalSchemaMappingCollection;
+ fdoPhysicalSchemaMappingCollection = fdoDescribeSchemaMappingCommand->Execute();
+ CHECKNULL((FdoPhysicalSchemaMappingCollection*)fdoPhysicalSchemaMappingCollection, L"MgServerGetSchemaMapping.GetSchemaMapping");
+
+ // Write to memory stream
+ fdoPhysicalSchemaMappingCollection->WriteXml(writer);
+
+ // Close the XML writer
+ writer->Close();
+
+ fmis->Reset(); // TODO: We should not be calling reset here. A defect in FDO should be fixed.
+
+ FdoInt64 len = fmis->GetLength();
+ m_bytes = new FdoByte[(size_t)len];
+ CHECKNULL(m_bytes, L"MgServerGetSchemaMapping.GetSchemaMapping");
+
+ fmis->Read(m_bytes, (FdoSize)len);
+
+ Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)m_bytes, (INT32)len);
+ byteSource->SetMimeType(MgMimeType::Xml);
+ byteReader = byteSource->GetReader();
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgServerGetSchemaMapping::GetSchemaMapping()", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerGetSchemaMapping.GetSchemaMapping")
+
+ return byteReader.Detach();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSchemaMapping.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_GET_SCHEMA_MAPPING_H_
+#define _MG_SERVER_GET_SCHEMA_MAPPING_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgServerGetSchemaMapping
+{
+public:
+ MgServerGetSchemaMapping();
+ ~MgServerGetSchemaMapping();
+
+
+ MgByteReader* GetSchemaMapping(CREFSTRING providerName, CREFSTRING partialConnString);
+
+private:
+ FdoByte* m_bytes;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,293 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "GetSpatialContexts.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "Services/Feature/FeatureServiceCache.h"
+#include "GeometryCommon.h"
+
+MgServerGetSpatialContexts::MgServerGetSpatialContexts()
+{
+ m_featureServiceCache = MgFeatureServiceCache::GetInstance();
+}
+
+MgServerGetSpatialContexts::~MgServerGetSpatialContexts()
+{
+}
+
+// Executes the GetSpatialContext command and creates a reader
+
+MgSpatialContextReader* MgServerGetSpatialContexts::GetSpatialContexts(MgResourceIdentifier* resId)
+{
+ Ptr<MgSpatialContextReader> mgSpatialContextReader;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ mgSpatialContextReader = m_featureServiceCache->GetSpatialContextReader(resId);
+
+ if (NULL == mgSpatialContextReader.p)
+ {
+ // Connect to provider
+ Ptr<MgFeatureConnection> msfc = new MgFeatureConnection(resId);
+
+ // Connection must be open to retrieve a list of available contexts.
+ if ((NULL != msfc.p) && ( msfc->IsConnectionOpen() ))
+ {
+ // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+ // otherwise it leaves the FDO connection marked as still in use.
+ FdoPtr<FdoIConnection> fdoConn = msfc->GetConnection();
+ m_providerName = msfc->GetProviderName();
+
+ Ptr<MgSpatialContextCacheItem> cacheItem = m_featureServiceCache->GetSpatialContextInfo(resId);
+ MgSpatialContextInfo* spatialContextInfo = cacheItem->Get();
+
+ // Check whether command is supported by provider
+ if (!msfc->SupportsCommand((INT32)FdoCommandType_GetSpatialContexts))
+ {
+ // TODO: specify which argument and message, once we have the mechanism
+ STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
+ throw new MgInvalidOperationException(L"MgServerGetSpatialContexts.GetSpatialContexts", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ FdoPtr<FdoIGetSpatialContexts> fdoCommand = (FdoIGetSpatialContexts*)fdoConn->CreateCommand(FdoCommandType_GetSpatialContexts);
+ CHECKNULL((FdoIGetSpatialContexts*)fdoCommand, L"MgServerGetSpatialContexts.GetSpatialContexts");
+
+ // Execute the command
+ FdoPtr<FdoISpatialContextReader> spatialReader = fdoCommand->Execute();
+ CHECKNULL((FdoISpatialContextReader*)spatialReader, L"MgServerGetSpatialContexts.GetSpatialContexts");
+
+ mgSpatialContextReader = new MgSpatialContextReader();
+ while (spatialReader->ReadNext())
+ {
+ // Set providername for which spatial reader is executed
+ mgSpatialContextReader->SetProviderName(m_providerName);
+
+ Ptr<MgSpatialContextData> spatialData = GetSpatialContextData(spatialReader, spatialContextInfo);
+ CHECKNULL((MgSpatialContextData*)spatialData, L"MgServerGetSpatialContexts.GetSpatialContexts");
+
+ // Add spatial data to the spatialcontext reader
+ mgSpatialContextReader->AddSpatialData(spatialData);
+ }
+
+ m_featureServiceCache->SetSpatialContextReader(resId, mgSpatialContextReader.p);
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgServerGetSpatialContexts.GetSpatialContexts()", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ }
+ else
+ {
+ //MgCacheManager::GetInstance()->CheckPermission(resId, MgResourcePermission::ReadOnly);
+ }
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resId, L"MgServerGetSpatialContexts.GetSpatialContexts")
+
+ return mgSpatialContextReader.Detach();
+}
+
+MgSpatialContextData* MgServerGetSpatialContexts::GetSpatialContextData(
+ FdoISpatialContextReader* spatialReader, MgSpatialContextInfo* spatialContextInfo)
+{
+ Ptr<MgSpatialContextData> spatialData = new MgSpatialContextData();
+
+ // Name must exist
+ FdoString* name = spatialReader->GetName();
+ CHECKNULL((FdoString*)name, L"MgServerGetSpatialContexts.GetSpatialContexts");
+ spatialData->SetName(STRING(name));
+
+ STRING coordSysName = L"";
+ FdoString* csName = spatialReader->GetCoordinateSystem();
+
+ Ptr<MgCoordinateSystemFactory> csFactory;
+ // WKT for co-ordinate system
+ FdoString* csWkt = NULL;
+ STRING srsWkt = L"";
+
+ bool haveValidCoordSys = false;
+ if(NULL != csName && *csName != '\0')
+ {
+ coordSysName = STRING(csName);
+ }
+ else
+ {
+ csWkt = spatialReader->GetCoordinateSystemWkt();
+ if (csWkt != NULL && *csWkt != '\0')
+ {
+ srsWkt = csWkt;
+ try
+ {
+ csFactory = new MgCoordinateSystemFactory();
+ coordSysName = csFactory->ConvertWktToCoordinateSystemCode(srsWkt);
+ haveValidCoordSys = (coordSysName.size() != 0);
+ }
+ catch (MgException* e)
+ {
+ SAFE_RELEASE(e);
+ }
+ catch(...)
+ {
+ }
+ }
+ }
+
+ bool spatialContextDefined = !coordSysName.empty();
+ bool coordSysOverridden = false;
+
+ // look for coordinate system override
+ if (NULL != spatialContextInfo)
+ {
+ // Perform substitution of missing coordinate system with
+ // the spatial context mapping defined in feature source document
+ MgSpatialContextInfo::const_iterator iter = spatialContextInfo->find(name);
+
+ if (spatialContextInfo->end() != iter)
+ {
+ csName = (iter->second).c_str();
+ coordSysOverridden = true;
+ }
+ }
+
+ if (csName != NULL && *csName != '\0')
+ {
+ spatialData->SetCoordinateSystem(STRING(csName));
+ }
+
+ // Desc for spatial context
+ STRING desc = L"";
+
+ // This flag is obsolete and will be deprecated.
+ bool isActive = spatialReader->IsActive();
+
+ if (coordSysOverridden)
+ {
+ srsWkt = csName;
+ desc = MgFeatureUtil::GetMessage(L"MgCoordinateSystemOverridden");
+ }
+ else if (spatialContextDefined && !coordSysOverridden)
+ {
+ // avoid looking one more time after CS in case we have a valid one...
+ if (!haveValidCoordSys)
+ {
+ csWkt = spatialReader->GetCoordinateSystemWkt();
+ if(NULL != csWkt && *csWkt != '\0')
+ srsWkt = csWkt;
+
+ if (srsWkt.empty())
+ {
+ try
+ {
+ if (csFactory == NULL)
+ csFactory = new MgCoordinateSystemFactory();
+
+ // Check if the spatial context coordinate system data represents an EPSG
+ // code. If this is the case the WKT data for the EPSG code has to be
+ // retrieved.
+ if (IsEpsgCodeRepresentation(csName))
+ {
+ // This is an EPSG code
+ FdoString* p = NULL;
+ if ((csName[0] == L'E') || (csName[0] == L'e'))
+ p = csName+5;
+ else
+ p = csName;
+
+ INT32 epsgCode = (INT32)wcstol(p, NULL, 10);
+
+ // Convert the EPSG numerical code to WKT
+ srsWkt = csFactory->ConvertEpsgCodeToWkt(epsgCode);
+ }
+ else
+ {
+ srsWkt = csFactory->ConvertCoordinateSystemCodeToWkt(STRING(csName));
+ }
+ }
+ catch (MgException* e)
+ {
+ SAFE_RELEASE(e);
+ }
+ catch(...)
+ {
+ // Just use the empty WKT.
+ }
+ }
+ }
+ FdoString* fdoDesc = spatialReader->GetDescription();
+ if(NULL != fdoDesc)
+ desc = STRING(fdoDesc);
+ }
+
+ // retrieve other values from spatialReader
+ FdoSpatialContextExtentType extentType = spatialReader->GetExtentType();
+ FdoPtr<FdoByteArray> byteArray = spatialReader->GetExtent();
+ double xyTol = spatialReader->GetXYTolerance();
+ double zTol = spatialReader->GetZTolerance();
+
+ spatialData->SetCoordinateSystemWkt(srsWkt);
+ spatialData->SetDescription(desc);
+ spatialData->SetExtentType((INT32)extentType);
+
+ if (byteArray.p != NULL)
+ {
+ INT32 size = (INT32)byteArray->GetCount();
+ BYTE_ARRAY_IN bytes = (BYTE_ARRAY_IN)byteArray->GetData();
+ Ptr<MgByte> extent = new MgByte(bytes, size);
+ spatialData->SetExtent(extent);
+ }
+
+ // XY Tolerance
+ spatialData->SetXYTolerance(xyTol);
+
+ // Z Tolerance
+ spatialData->SetZTolerance(zTol);
+
+ // This flag is obsolete and will be deprecated.
+ spatialData->SetActiveStatus(isActive);
+
+ return spatialData.Detach();
+}
+
+bool MgServerGetSpatialContexts::IsEpsgCodeRepresentation (FdoString *coordSysName)
+{
+ // If the given coordinate system name is NULL or not NULL but empty
+ // return false as those cases do not represent an EPSG code.
+ if ((coordSysName == NULL) || (coordSysName[0] == L'\0'))
+ return false;
+
+ // Check if the string contains a coded EPSG number ("EPSG:<num>"). If this
+ // is the case return true;
+ size_t coordSysNameLength = wcslen(coordSysName);
+ if (coordSysNameLength > 5)
+ if (((coordSysName[0] == L'E') || (coordSysName[0] == L'e')) &&
+ ((coordSysName[1] == L'P') || (coordSysName[1] == L'p')) &&
+ ((coordSysName[2] == L'S') || (coordSysName[2] == L's')) &&
+ ((coordSysName[3] == L'G') || (coordSysName[3] == L'g')) &&
+ (coordSysName[4] == L':') )
+ return true;
+
+ // The string does not contain a coded EPSG number. Next, check if the
+ // string represents a numeric value. If this is the case then the value
+ // represents an EPSG code and the routine has to return true.
+ for (size_t i = 0; i < coordSysNameLength; i++)
+ if (!iswdigit(coordSysName[i]))
+ return false;
+
+ // This is an EPSG code. Indicate so.
+ return true;
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/GetSpatialContexts.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef MG_SERVERGETSPATIALCONTEXTS_H_
+#define MG_SERVERGETSPATIALCONTEXTS_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgFeatureServiceCache;
+
+class MgServerGetSpatialContexts
+{
+public:
+ MgServerGetSpatialContexts();
+ ~MgServerGetSpatialContexts();
+ MgSpatialContextReader* GetSpatialContexts(MgResourceIdentifier* resId);
+
+private:
+ MgSpatialContextData* GetSpatialContextData(FdoISpatialContextReader* spatialReader,
+ MgSpatialContextInfo* spatialContextInfo);
+
+ // ==========================================================================
+ // ===================== EPSG RELATED UTILITY FUNCTIONS =====================
+ // ==========================================================================
+ // Checks whether or not the coordinate system name represents an EPSG code.
+ // If this is the case the routine returns TRUE, FALSE otherwise.
+ bool IsEpsgCodeRepresentation (FdoString *coordSysName);
+
+ STRING m_providerName;
+ MgFeatureServiceCache* m_featureServiceCache;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,256 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "FeatureManipulationCommand.h"
+#include "InsertCommand.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "Services/FeatureReader.h"
+#include "Services/Feature/FeatureSetReader.h"
+
+MgServerInsertCommand::MgServerInsertCommand()
+{
+ m_srvrFeatConn = NULL;
+ m_featCommand = NULL;
+}
+
+MgServerInsertCommand::MgServerInsertCommand(MgFeatureCommand* command, MgFeatureConnection* connection, INT32 cmdId)
+{
+ CHECKNULL(command, L"MgServerInsertCommand.MgServerInsertCommand");
+ CHECKNULL(connection, L"MgServerInsertCommand.MgServerInsertCommand");
+
+ m_srvrFeatConn = SAFE_ADDREF((MgFeatureConnection*)connection);
+ m_featCommand = SAFE_ADDREF((MgInsertFeatures*)command);
+ m_cmdId = cmdId;
+}
+
+MgServerInsertCommand::~MgServerInsertCommand()
+{
+ m_srvrFeatConn = NULL;
+}
+
+MgProperty* MgServerInsertCommand::Execute()
+{
+ Ptr<MgFeatureProperty> prop;
+
+ STRING clsName = m_featCommand->GetFeatureClassName();
+ Ptr<MgBatchPropertyCollection> srcCol = m_featCommand->GetBatchPropertyValues();
+
+ if ((srcCol == NULL) || srcCol->GetCount() == 0)
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgNoFeaturesForInsert");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerInsertCommand::Execute", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ FdoPtr<FdoIConnection> fdoConn = m_srvrFeatConn->GetConnection();
+
+ // Create the SQL command
+ FdoPtr<FdoIInsert> fdoCommand = (FdoIInsert*)fdoConn->CreateCommand(FdoCommandType_Insert);
+ CHECKNULL((FdoIInsert*)fdoCommand, L"MgServerInsertCommand.Execute");
+
+ fdoCommand->SetFeatureClassName(clsName.c_str());
+
+ // TODO: Fdo returns NULL here for Oracle and SDF, ArcSDE supports it.
+ FdoPtr<FdoBatchParameterValueCollection> bParamValCol = fdoCommand->GetBatchParameterValues();
+ if (bParamValCol != NULL && bParamValCol->GetCount() > 1)
+ {
+ prop = BatchInsert(srcCol, bParamValCol, fdoCommand, fdoConn);
+ }
+ else
+ {
+ FdoPtr<FdoPropertyValueCollection> propValCol = fdoCommand->GetPropertyValues();
+ prop = SingleInsert(srcCol, propValCol, fdoCommand, fdoConn);
+ }
+
+ return prop.Detach();
+}
+
+MgFeatureProperty* MgServerInsertCommand::BatchInsert( MgBatchPropertyCollection* srcCol,
+ FdoBatchParameterValueCollection* bParamValCol,
+ FdoIInsert* fdoCommand,
+ FdoIConnection* fdoConn)
+{
+ INT32 cnt = srcCol->GetCount();
+ for (INT32 i = 0; i < cnt; i++)
+ {
+ Ptr<MgPropertyCollection> propCol = srcCol->GetItem(i);
+ FdoPtr<FdoParameterValueCollection> paramCol = MgFeatureUtil::CreateFdoParameterCollection(propCol);
+ bParamValCol->Add(paramCol);
+ }
+ FdoPtr<FdoIFeatureReader> reader = fdoCommand->Execute();
+ CHECKNULL((FdoIFeatureReader*)reader, L"MgServerInsertCommand.BatchInsert");
+
+ // TODO: This is FDO defect, they should not require ReadNext() for class definition
+ bool available = false;
+ try
+ {
+ available = reader->ReadNext();
+ }
+ catch(FdoException* e)
+ {
+ FDO_SAFE_RELEASE(e);
+ available = false;
+ }
+ catch (...)
+ {
+ available = false;
+ }
+
+ if (!available)
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgInsertError");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerGwsGetFeatures.BatchInsert", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ char buff[32];
+ sprintf(buff, "%d", m_cmdId);
+ STRING str = MgUtil::MultiByteToWideChar(string(buff));
+
+ Ptr<MgFeatureReader> mgFeatureReader = new MgdFeatureReader(m_srvrFeatConn, reader);
+ return new MgFeatureProperty(str, mgFeatureReader);
+}
+
+MgFeatureProperty* MgServerInsertCommand::SingleInsert( MgBatchPropertyCollection* srcCol,
+ FdoPropertyValueCollection* propValCol,
+ FdoIInsert* fdoCommand,
+ FdoIConnection* fdoConn )
+{
+ Ptr<MgFeatureSet> featureSet = new MgFeatureSet();
+ featureSet->SetClassDefinition(NULL);
+ Ptr<MgPropertyDefinitionCollection> keyProps;
+
+ INT32 cnt = srcCol->GetCount();
+ for (INT32 i=0; i<cnt; i++)
+ {
+ Ptr<MgPropertyCollection> propCol = srcCol->GetItem(i);
+
+ propValCol->Clear();
+ MgFeatureUtil::FillFdoPropertyCollection(propCol, propValCol);
+
+ FdoPtr<FdoIFeatureReader> reader = fdoCommand->Execute();
+ CHECKNULL((FdoIFeatureReader*)reader, L"MgServerInsertCommand.SingleInsert");
+
+ if (keyProps == NULL)
+ {
+ FdoPtr<FdoClassDefinition> classDef = reader->GetClassDefinition();
+ FdoPtr<FdoDataPropertyDefinitionCollection> idProps = classDef->GetIdentityProperties();
+ if (idProps->GetCount() > 0)
+ {
+ keyProps = new MgPropertyDefinitionCollection();
+ MgFeatureUtil::GetClassProperties(keyProps, idProps);
+ }
+ }
+
+ if (keyProps == NULL)
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgInsertError");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerInsertCommand.SingleInsert", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ bool available = false;
+ try
+ {
+ available = reader->ReadNext();
+ }
+ catch(FdoException* e)
+ {
+ FDO_SAFE_RELEASE(e);
+ available = false;
+ }
+ catch (...)
+ {
+ available = false;
+ }
+
+ if (!available)
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgInsertError");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerInsertCommand.SingleInsert", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ // Performance improvement: Only return the key values
+ Ptr<MgPropertyCollection> idProperties = new MgPropertyCollection();
+ INT32 nProps = keyProps->GetCount();
+ for (int j=0; j<nProps; j++)
+ {
+ Ptr<MgDataPropertyDefinition> propDef = dynamic_cast<MgDataPropertyDefinition*>(keyProps->GetItem(j));
+ if (propDef == NULL) continue;
+
+ //TODO: should we use qualified name here?
+ STRING propName = propDef->GetName();
+ INT32 propType = propDef->GetDataType();
+ switch (propType)
+ {
+ case MgPropertyType::Int16:
+ {
+ Ptr<MgInt16Property> intProp = new MgInt16Property(propName, reader->GetInt16(propName.c_str()));
+ idProperties->Add(intProp);
+ }
+ break;
+
+ case MgPropertyType::Int32:
+ {
+ Ptr<MgInt32Property> intProp = new MgInt32Property(propName, reader->GetInt32(propName.c_str()));
+ idProperties->Add(intProp);
+ }
+ break;
+
+ case MgPropertyType::Int64:
+ {
+ Ptr<MgInt64Property> intProp = new MgInt64Property(propName, reader->GetInt64(propName.c_str()));
+ idProperties->Add(intProp);
+ }
+ break;
+
+ case MgPropertyType::String:
+ {
+ Ptr<MgStringProperty> strProp = new MgStringProperty(propName, reader->GetString(propName.c_str()));
+ idProperties->Add(strProp);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ featureSet->AddFeature(idProperties);
+ }
+
+ Ptr<MgFeatureReader> featureSetReader = new MgdFeatureSetReader(featureSet);
+
+ char buff[32];
+ sprintf(buff, "%d", m_cmdId);
+ STRING str = MgUtil::MultiByteToWideChar(string(buff));
+
+ return new MgFeatureProperty(str, featureSetReader);
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/InsertCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_INSERT_COMMAND_H_
+#define _MG_SERVER_INSERT_COMMAND_H_
+
+class MgFeatureConnection;
+
+class MgServerInsertCommand : public MgFeatureManipulationCommand
+{
+ DECLARE_CLASSNAME(MgServerInsertCommand)
+
+public:
+ MgServerInsertCommand(MgFeatureCommand* command, MgFeatureConnection* connection, INT32 cmdId);
+ virtual MgProperty* Execute();
+protected:
+ MgServerInsertCommand();
+ ~MgServerInsertCommand();
+
+ MgFeatureProperty* BatchInsert( MgBatchPropertyCollection* srcCol,
+ FdoBatchParameterValueCollection* bParamValCol,
+ FdoIInsert* fdoCommand,
+ FdoIConnection* fdoConn );
+
+ MgFeatureProperty* SingleInsert( MgBatchPropertyCollection* srcCol,
+ FdoPropertyValueCollection* bParamValCol,
+ FdoIInsert* fdoCommand,
+ FdoIConnection* fdoConn );
+
+private:
+ Ptr<MgInsertFeatures> m_featCommand;
+ Ptr<MgFeatureConnection> m_srvrFeatConn;
+ INT32 m_cmdId;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,340 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "FeatureServiceCommand.h"
+#include "SelectCommand.h"
+#include "SelectAggregateCommand.h"
+#include "Services/DataReader.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FdoForcedOneToOneFeatureReader.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "FdoExpressionEngine.h"
+#include "Util/FdoExpressionEngineUtilDataReader.h"
+
+
+MgSelectAggregateCommand::MgSelectAggregateCommand(MgResourceIdentifier* resource)
+{
+ CHECKNULL((MgResourceIdentifier*)resource, L"MgSelectAggregateCommand.MgSelectAggregateCommand");
+
+ // Connect to provider
+ m_connection = new MgFeatureConnection(resource);
+ if ((NULL != m_connection.p) && ( m_connection->IsConnectionOpen() ))
+ {
+ m_providerName = m_connection->GetProviderName();
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgSelectAggregateCommand.MgSelectAggregateCommand", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ // Create FdoISelectAggregates command
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ m_command = (FdoISelectAggregates*)fdoConn->CreateCommand(FdoCommandType_SelectAggregates);
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.MgSelectAggregateCommand");
+}
+
+MgSelectAggregateCommand::~MgSelectAggregateCommand()
+{
+ m_command = NULL;
+ m_filter = NULL;
+}
+
+FdoIdentifierCollection* MgSelectAggregateCommand::GetPropertyNames()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetPropertyNames");
+ return m_command->GetPropertyNames();
+}
+
+void MgSelectAggregateCommand::SetDistinct(bool value)
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetDistinct");
+ m_command->SetDistinct(value);
+}
+
+bool MgSelectAggregateCommand::GetDistinct()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetDistinct");
+ return m_command->GetDistinct();
+}
+
+void MgSelectAggregateCommand::SetFetchSize(FdoInt32 fetchSize)
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetFetchSize");
+ m_command->SetFetchSize(fetchSize);
+}
+
+FdoInt32 MgSelectAggregateCommand::GetFetchSize()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetFetchSize");
+ return m_command->GetFetchSize();
+}
+
+FdoIdentifierCollection* MgSelectAggregateCommand::GetOrdering()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetOrdering");
+ return m_command->GetOrdering();
+}
+
+void MgSelectAggregateCommand::SetOrderingOption(FdoOrderingOption option)
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetOrderingOption");
+ m_command->SetOrderingOption(option);
+}
+
+FdoOrderingOption MgSelectAggregateCommand::GetOrderingOption()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetOrderingOption");
+ return m_command->GetOrderingOption();
+}
+
+FdoIdentifierCollection* MgSelectAggregateCommand::GetGrouping()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetGrouping");
+ return m_command->GetGrouping();
+}
+
+void MgSelectAggregateCommand::SetGroupingFilter(FdoFilter* filter)
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetGroupingFilter");
+ m_command->SetGroupingFilter(filter);
+}
+
+FdoFilter* MgSelectAggregateCommand::GetGroupingFilter()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetGroupingFilter");
+ return m_command->GetGroupingFilter();
+}
+
+void MgSelectAggregateCommand::SetFeatureClassName(FdoString* value)
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetFeatureClassName");
+ m_command->SetFeatureClassName(value);
+}
+
+void MgSelectAggregateCommand::SetFilter(FdoString* value)
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetFilter");
+ m_command->SetFilter(value);
+}
+
+void MgSelectAggregateCommand::SetFilter(FdoFilter* value)
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetFilter");
+ m_command->SetFilter(value);
+
+ m_filter = FDO_SAFE_ADDREF(value);
+}
+
+MgReader* MgSelectAggregateCommand::Execute()
+{
+ // Execute the command
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.Execute");
+ FdoPtr<FdoIDataReader> dataReader = m_command->Execute();
+ CHECKNULL((FdoIDataReader*)dataReader, L"MgSelectAggregateCommand.Execute");
+
+ // Create a feature reader identifier
+ return new MgdDataReader(m_connection, dataReader); //, m_providerName);
+}
+
+bool MgSelectAggregateCommand::IsSupportedFunction(FdoFunction* fdoFunc)
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return this->IsFdoSupportedFunction(fdoConn, fdoFunc);
+}
+
+bool MgSelectAggregateCommand::SupportsSelectGrouping()
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return MgFeatureServiceCommand::SupportsSelectGrouping(fdoConn);
+}
+
+bool MgSelectAggregateCommand::SupportsSelectOrdering()
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return MgFeatureServiceCommand::SupportsSelectOrdering(fdoConn);
+}
+
+bool MgSelectAggregateCommand::SupportsSelectDistinct()
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return MgFeatureServiceCommand::SupportsSelectDistinct(fdoConn);
+}
+
+FdoFilter* MgSelectAggregateCommand::GetFilter()
+{
+ return FDO_SAFE_ADDREF(m_filter.p);
+}
+
+FdoJoinCriteriaCollection* MgSelectAggregateCommand::GetJoinCriteria()
+{
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.GetJoinCriteria");
+ return m_command->GetJoinCriteria();
+}
+
+void MgSelectAggregateCommand::SetAlias(FdoString* alias)
+{
+ CHECKARGUMENTNULL(alias, L"MgSelectAggregateCommand.SetAlias");
+ CHECKNULL((FdoISelectAggregates*)m_command, L"MgSelectAggregateCommand.SetAlias");
+ m_command->SetAlias(alias);
+}
+
+MgReader* MgSelectAggregateCommand::ExecuteJoined(MgStringCollection* idPropNames, bool bForceOneToOne)
+{
+ Ptr<MgReader> ret;
+
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ FdoPtr<FdoISelect> select = static_cast<FdoISelect*>(fdoConn->CreateCommand(FdoCommandType_Select));
+
+ FdoPtr<FdoIdentifier> clsName = m_command->GetFeatureClassName();
+ select->SetFeatureClassName(clsName);
+
+
+ STRING clsNameStr = clsName->GetText();
+ STRING schemaName;
+ STRING className;
+ MgUtil::ParseQualifiedClassName(clsNameStr, schemaName, className);
+
+ FdoPtr<FdoIdentifierCollection> selectedIds = GetPropertyNames();
+ FdoPtr<FdoIdentifierCollection> computedIds = FdoIdentifierCollection::Create();
+ for (FdoInt32 i = 0; i < selectedIds->GetCount(); i++)
+ {
+ FdoPtr<FdoIdentifier> identifier = selectedIds->GetItem(i);
+ if (identifier->GetExpressionType() == FdoExpressionItemType_ComputedIdentifier)
+ {
+ FdoComputedIdentifier* comp = static_cast<FdoComputedIdentifier*>(identifier.p);
+ FdoPtr<FdoExpression> expr = comp->GetExpression();
+ if (expr->GetExpressionType() == FdoExpressionItemType_Function)
+ computedIds->Add(identifier);
+ }
+ }
+ FdoPtr<FdoClassDefinition> originalClassDef;
+
+ FdoPtr<FdoIDescribeSchema> descSchema = static_cast<FdoIDescribeSchema*>(fdoConn->CreateCommand(FdoCommandType_DescribeSchema));
+ if (!schemaName.empty())
+ {
+ descSchema->SetSchemaName(schemaName.c_str());
+ }
+ if (!className.empty())
+ {
+ FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
+ classNames->Add(className.c_str());
+ descSchema->SetClassNames(classNames);
+ }
+
+ FdoPtr<FdoClassDefinition> classDef;
+ FdoPtr<FdoFeatureSchemaCollection> schemas = descSchema->Execute();
+ for (FdoInt32 i = 0; i < schemas->GetCount(); i++)
+ {
+ FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(i);
+ if (wcscmp(schema->GetName(), schemaName.c_str()) == 0)
+ {
+ FdoPtr<FdoClassCollection> classes = schema->GetClasses();
+ for (FdoInt32 j = 0; j < classes->GetCount(); j++)
+ {
+ FdoPtr<FdoClassDefinition> klassDef = classes->GetItem(j);
+ if (wcscmp(klassDef->GetName(), className.c_str()) == 0)
+ {
+ originalClassDef = SAFE_ADDREF(klassDef.p);
+ break;
+ }
+ }
+ }
+ }
+
+
+ if (NULL != (FdoFilter*)m_filter)
+ select->SetFilter(m_filter);
+
+ FdoCommonExpressionType exprType;
+ FdoPtr<FdoFunctionDefinitionCollection> functions = FdoExpressionEngine::GetStandardFunctions();
+ FdoPtr<FdoArray<FdoFunction*> > aggrIdents = FdoExpressionEngineUtilDataReader::GetAggregateFunctions(functions, computedIds, exprType);
+
+ FdoPtr<FdoIFeatureReader> reader;
+ FdoPtr<FdoIdentifierCollection> ids;
+ FdoPtr<FdoIdentifierCollection> orderBy = m_command->GetOrdering();
+ FdoOrderingOption orderOpt = m_command->GetOrderingOption();
+
+ //n00bism: String goes in, garbage comes out. Anyway, we know the alias we want to set
+ select->SetAlias(PRIMARY_ALIAS);
+ //select->SetAlias(m_command->GetAlias());
+
+ FdoPtr<FdoJoinCriteriaCollection> srcCriteria = GetJoinCriteria();
+ FdoPtr<FdoJoinCriteriaCollection> dstCriteria = select->GetJoinCriteria();
+ for (FdoInt32 i = 0; i < srcCriteria->GetCount(); i++)
+ {
+ FdoPtr<FdoJoinCriteria> criteria = srcCriteria->GetItem(i);
+ dstCriteria->Add(criteria);
+ }
+
+ if ((aggrIdents != NULL) && (aggrIdents->GetCount() > 0))
+ {
+ reader = select->Execute();
+ }
+ else
+ {
+ // transfer over the identifiers to the basic select command:
+ ids = select->GetPropertyNames();
+ ids->Clear();
+ if (0 == selectedIds->GetCount())
+ {
+ FdoPtr<FdoPropertyDefinitionCollection> propDefs = originalClassDef->GetProperties();
+ for (int i=0; i<propDefs->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition> propDef = propDefs->GetItem(i);
+ FdoPtr<FdoIdentifier> localId = FdoIdentifier::Create(propDef->GetName());
+ ids->Add(localId);
+ }
+ FdoPtr<FdoReadOnlyPropertyDefinitionCollection> basePropDefs = originalClassDef->GetBaseProperties();
+ for (int i=0; i<basePropDefs->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition> basePropDef = basePropDefs->GetItem(i);
+ FdoPtr<FdoIdentifier> localId = FdoIdentifier::Create(basePropDef->GetName());
+ ids->Add(localId);
+ }
+ }
+ else
+ {
+ for (int i=0; i<selectedIds->GetCount(); i++)
+ {
+ FdoPtr<FdoIdentifier> localId = selectedIds->GetItem(i);
+ ids->Add(localId);
+ }
+ }
+
+ // Execute the basic select command:
+ reader = select->Execute();
+ }
+
+ if (bForceOneToOne)
+ {
+ FdoPtr<FdoStringCollection> names = MgFeatureUtil::MgToFdoStringCollection(idPropNames, false);
+ FdoPtr<FdoIFeatureReader> forcedReader = new MgFdoForcedOneToOneFeatureReader(reader, names);
+ FdoPtr<FdoIDataReader> dataReader = new FdoExpressionEngineUtilDataReader(functions, forcedReader, originalClassDef, computedIds, GetDistinct(), orderBy, orderOpt, ids, aggrIdents);
+
+ ret = new MgdDataReader(m_connection, dataReader); //, m_providerName);
+ }
+ else
+ {
+ FdoPtr<FdoIDataReader> dataReader = new FdoExpressionEngineUtilDataReader(functions, reader, originalClassDef, computedIds, GetDistinct(), orderBy, orderOpt, ids, aggrIdents);
+
+ ret = new MgdDataReader(m_connection, dataReader); //, m_providerName);
+ }
+
+ return ret.Detach();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectAggregateCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,74 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MGSELECTAGGREGATECOMMAND_H_
+#define _MGSELECTAGGREGATECOMMAND_H_
+
+class MgSelectAggregateCommand : public MgFeatureServiceCommand
+{
+ DECLARE_CLASSNAME(MgSelectAggregateCommand)
+
+public:
+ MgSelectAggregateCommand(MgResourceIdentifier* resource);
+ virtual ~MgSelectAggregateCommand();
+
+ virtual FdoIdentifierCollection* GetPropertyNames();
+
+ virtual void SetDistinct( bool value );
+ virtual bool GetDistinct( );
+
+ virtual void SetFetchSize(FdoInt32 fetchSize);
+ virtual FdoInt32 GetFetchSize();
+
+ virtual FdoIdentifierCollection* GetOrdering();
+ virtual void SetOrderingOption( FdoOrderingOption option );
+ virtual FdoOrderingOption GetOrderingOption( );
+
+ virtual FdoIdentifierCollection* GetGrouping();
+ virtual void SetGroupingFilter( FdoFilter* filter );
+ virtual FdoFilter* GetGroupingFilter( );
+
+ virtual void SetFeatureClassName(FdoString* value);
+ virtual void SetFilter(FdoString* value);
+ virtual void SetFilter(FdoFilter* value);
+
+ virtual FdoFilter* GetFilter();
+
+ virtual MgReader* Execute();
+ MgReader* ExecuteJoined(MgStringCollection* idPropNames, bool bForceOneToOne);
+ virtual bool IsSupportedFunction(FdoFunction* fdoFunc);
+ virtual bool SupportsSelectGrouping();
+ virtual bool SupportsSelectOrdering();
+ virtual bool SupportsSelectDistinct();
+
+ virtual void Dispose()
+ {
+ delete this;
+ }
+
+ virtual FdoJoinCriteriaCollection* GetJoinCriteria();
+ virtual void SetAlias(FdoString* alias);
+
+private:
+ Ptr<MgFeatureConnection> m_connection;
+ STRING m_providerName;
+ FdoPtr<FdoISelectAggregates> m_command;
+
+ FdoPtr<FdoFilter> m_filter;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,432 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "FeatureServiceCommand.h"
+#include "SelectCommand.h"
+#include "SelectAggregateCommand.h"
+#include "Services/FeatureReader.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/Feature/FdoFeatureReader.h"
+#include "Services/Feature/FdoFilterCollection.h"
+#include "Services/Feature/FdoReaderCollection.h"
+
+// The maximum size of the subfilter for a selection query. Tune this value for optimal selection perfomance.
+#define MG_MAX_SUBFILTER_SIZE 250
+
+MgSelectCommand::MgSelectCommand(MgResourceIdentifier* resource)
+{
+ CHECKNULL((MgResourceIdentifier*)resource, L"MgSelectCommand.MgSelectCommand");
+
+ // Connect to provider
+ m_connection = new MgFeatureConnection(resource);
+ if ((NULL != m_connection.p) && ( m_connection->IsConnectionOpen() ))
+ {
+ m_providerName = m_connection->GetProviderName();
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgSelectCommand.MgSelectCommand", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ // Create FdoISelect command
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ m_command = (FdoISelect*)fdoConn->CreateCommand(FdoCommandType_Select);
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.MgSelectCommand");
+}
+
+MgSelectCommand::~MgSelectCommand()
+{
+ m_command = NULL;
+ m_filter = NULL;
+}
+
+FdoIdentifierCollection* MgSelectCommand::GetPropertyNames()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetPropertyNames");
+ return m_command->GetPropertyNames();
+}
+
+void MgSelectCommand::SetDistinct(bool value)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetDistinct");
+ // This operation is not supported by FdoISelect
+ // m_command->SetDistinct(value);
+
+ // throw new MgInvalidOperationException(L"MgSelectCommand.SetDistinct", __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
+bool MgSelectCommand::GetDistinct()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetDistinct");
+ // This operation is not supported by FdoISelect
+ // return m_command->GetDistinct();
+
+ // throw new MgInvalidOperationException(L"MgSelectCommand.GetDistinct", __LINE__, __WFILE__, NULL, L"", NULL);
+
+ return false;
+}
+
+void MgSelectCommand::SetFetchSize(FdoInt32 fetchSize)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetFetchSize");
+ m_command->SetFetchSize(fetchSize);
+}
+
+FdoInt32 MgSelectCommand::GetFetchSize()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetFetchSize");
+ return m_command->GetFetchSize();
+}
+
+FdoIdentifierCollection* MgSelectCommand::GetOrdering()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetOrdering");
+ return m_command->GetOrdering();
+}
+
+void MgSelectCommand::SetOrderingOption(FdoOrderingOption option)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetOrderingOption");
+ m_command->SetOrderingOption(option);
+}
+
+FdoOrderingOption MgSelectCommand::GetOrderingOption()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetOrderingOption");
+ return m_command->GetOrderingOption();
+}
+
+FdoIdentifierCollection* MgSelectCommand::GetGrouping()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetGrouping");
+ // This operation is not supported by FdoISelect
+ // return m_command->GetGrouping();
+
+ // throw new MgInvalidOperationException(L"MgSelectCommand.GetGrouping", __LINE__, __WFILE__, NULL, L"", NULL);
+ return NULL;
+}
+
+void MgSelectCommand::SetGroupingFilter(FdoFilter* filter)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetGroupingFilter");
+ // This operation is not supported by FdoISelect
+ // m_command->SetGroupingFilter(filter);
+
+ // throw new MgInvalidOperationException(L"MgSelectCommand.SetGroupingFilter", __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
+FdoFilter* MgSelectCommand::GetGroupingFilter()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetGroupingFilter");
+ // This operation is not supported by FdoISelect
+ // return m_command->GetGroupingFilter(filter);
+
+ // throw new MgInvalidOperationException(L"MgSelectCommand.GetGroupingFilter", __LINE__, __WFILE__, NULL, L"", NULL);
+ return NULL;
+}
+
+void MgSelectCommand::SetFeatureClassName(FdoString* value)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetFeatureClassName");
+ m_command->SetFeatureClassName(value);
+}
+
+void MgSelectCommand::SetFilter(FdoString* value)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetFilter");
+ m_command->SetFilter(value);
+}
+
+void MgSelectCommand::SetFilter(FdoFilter* value)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetFilter");
+ m_command->SetFilter(value);
+
+ m_filter = FDO_SAFE_ADDREF(value);
+}
+
+MgReader* MgSelectCommand::Execute()
+{
+ FdoPtr<FdoIFeatureReader> reader;
+
+ // Break up the filter into smaller chunks
+ FdoPtr<MgFdoFilterCollection> subFilters = this->GetSubFilters();
+
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.Execute");
+
+ // Execute queries using the smaller filters and collect the results of the queries into a reader collection.
+ FdoPtr<MgFdoReaderCollection> frc = MgFdoReaderCollection::Create();
+
+ for (FdoInt32 filterIndex = 0; filterIndex < subFilters->GetCount(); filterIndex++)
+ {
+ FdoPtr<FdoFilter> filter = subFilters->GetItem(filterIndex);
+ m_command->SetFilter(filter);
+ reader = m_command->Execute();
+
+ frc->Add(reader);
+ }
+
+ FdoPtr<MgFdoFeatureReader> featureReader = new MgFdoFeatureReader(frc);
+ CHECKNULL((FdoIFeatureReader*)featureReader, L"MgSelectCommand.Execute");
+
+ return new MgdFeatureReader(m_connection, featureReader);
+}
+
+bool MgSelectCommand::IsSupportedFunction(FdoFunction* fdoFunc)
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return this->IsFdoSupportedFunction(fdoConn, fdoFunc);
+}
+
+bool MgSelectCommand::SupportsSelectGrouping()
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return MgFeatureServiceCommand::SupportsSelectGrouping(fdoConn);
+}
+
+bool MgSelectCommand::SupportsSelectOrdering()
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return MgFeatureServiceCommand::SupportsSelectOrdering(fdoConn);
+}
+
+bool MgSelectCommand::SupportsSelectDistinct()
+{
+ FdoPtr<FdoIConnection> fdoConn = m_connection->GetConnection();
+ return MgFeatureServiceCommand::SupportsSelectDistinct(fdoConn);
+}
+
+FdoFilter* MgSelectCommand::GetFilter()
+{
+ return FDO_SAFE_ADDREF(m_filter.p);
+}
+
+MgFdoFilterCollection* MgSelectCommand::GetSubFilters()
+{
+ // Break up a filter into a bunch of smaller filters
+
+ // For now we just reduce a simple case with datastore limitations in handling the number of OR conditions.
+ // This is the case where a filter has only OR spatial conditions that can be broken up into a collection
+ // of smaller OR filters.
+
+ class FdoCommonFilterFragmenter : public virtual FdoIFilterProcessor
+ {
+ private:
+ FdoPtr<FdoFilter> m_newFilter;
+ FdoPtr<FdoIGeometry> m_geomRight;
+ FdoPtr<FdoIGeometry> m_geomLeft;
+
+ int m_OrCount;
+ std::vector<FdoFilter*> m_filters;
+ bool m_isFragmented;
+
+ protected:
+ void HandleFilter( FdoFilter *filter )
+ {
+ filter->Process( this );
+ }
+ public:
+
+ FdoCommonFilterFragmenter( ):m_isFragmented(true)
+ {
+ m_OrCount = 0;
+ m_filters.clear();
+ }
+
+ int GetOrCount() { return m_OrCount; }
+ std::vector<FdoFilter*>& GetFilters() { return m_filters; }
+ bool IsFragmented() { return m_isFragmented; }
+ FdoFilter* GetNewFilter() { return m_newFilter ? FDO_SAFE_ADDREF(m_newFilter.p) : NULL; }
+
+ virtual void Dispose()
+ {
+ delete this;
+ }
+
+ virtual void ProcessBinaryLogicalOperator(FdoBinaryLogicalOperator& filter)
+ {
+ if( filter.GetOperation() != FdoBinaryLogicalOperations_Or )
+ {
+ m_isFragmented = false;
+ return;
+ }
+
+ HandleFilter( FdoPtr<FdoFilter>(filter.GetRightOperand()) );
+ m_newFilter = filter.GetLeftOperand();
+
+ m_OrCount++;
+ }
+ virtual void ProcessComparisonCondition(FdoComparisonCondition& filter)
+ {
+ // Add filter to collection
+ m_filters.push_back(&filter);
+ return;
+ }
+ virtual void ProcessDistanceCondition(FdoDistanceCondition& filter)
+ {
+ m_isFragmented = false;
+ return;
+ }
+
+ virtual void ProcessInCondition(FdoInCondition& filter)
+ {
+ m_isFragmented = false;
+ return;
+ }
+ virtual void ProcessNullCondition(FdoNullCondition& filter)
+ {
+ m_isFragmented = false;
+ return;
+ }
+ virtual void ProcessSpatialCondition(FdoSpatialCondition& filter)
+ {
+ m_isFragmented = false;
+ return;
+ }
+
+ virtual void ProcessUnaryLogicalOperator(FdoUnaryLogicalOperator& filter)
+ {
+ m_isFragmented = false;
+ return;
+ }
+ };
+
+
+ FdoCommonFilterFragmenter fragmenter;
+ if (m_filter)
+ m_filter->Process( &fragmenter );
+
+ FdoPtr<FdoFilter> newFilter = fragmenter.GetNewFilter();
+ while (newFilter != NULL)
+ {
+ newFilter->Process( &fragmenter );
+ FdoPtr<FdoFilter> tempFilter = fragmenter.GetNewFilter();
+ if (tempFilter != newFilter)
+ {
+ newFilter = tempFilter;
+ }
+ else
+ {
+ newFilter = NULL;
+ }
+ }
+
+#ifdef _DEBUG
+ int nCount = fragmenter.GetOrCount();
+ if ( nCount > 0)
+ {
+ char temp[1024];
+ sprintf(temp, "Or_Count = %d", nCount); // NOXLATE
+ printf("%s\n", temp);
+ }
+#endif
+
+ FdoPtr<MgFdoFilterCollection> filters = MgFdoFilterCollection::Create();
+
+ if (fragmenter.IsFragmented() && fragmenter.GetOrCount() > 0)
+ {
+ int nSelectionCount = 0;
+
+ std::vector<FdoFilter*>::iterator filterIter;
+ bool bFirst = true;
+
+ FdoStringP filterString;
+ std::vector<FdoFilter*>& fragmentedFilters = fragmenter.GetFilters();
+
+
+ bool bIsAddedToCollection = false;
+
+ for (filterIter = fragmentedFilters.begin(); filterIter != fragmentedFilters.end(); filterIter++)
+ {
+ FdoStringP tempString = (*filterIter)->ToString();
+ FdoStringP orString = L" OR "; // NOXLATE
+ if (bFirst)
+ {
+ filterString = tempString;
+ bFirst = false;
+ }
+ else
+ {
+ filterString = filterString + orString + tempString;
+ nSelectionCount++;
+ }
+
+ if (nSelectionCount >= MG_MAX_SUBFILTER_SIZE)
+ {
+ FdoPtr<FdoFilter> filter = FdoFilter::Parse(filterString);
+ filters->Add(filter);
+ bFirst = true;
+ filterString = L"";
+ nSelectionCount = 0;
+ bIsAddedToCollection = true;
+ }
+ else
+ {
+ bIsAddedToCollection = false;
+ }
+ }
+
+ if ( !bIsAddedToCollection )
+ {
+ FdoPtr<FdoFilter> filter = FdoFilter::Parse(filterString);
+ filters->Add(filter);
+ }
+
+ }
+ else
+ {
+ filters->Add(m_filter);
+ }
+
+ return filters.Detach();
+}
+
+FdoJoinCriteriaCollection* MgSelectCommand::GetJoinCriteria()
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.GetJoinCriteria");
+ return m_command->GetJoinCriteria();
+}
+
+void MgSelectCommand::SetAlias(FdoString* alias)
+{
+ CHECKNULL((FdoISelect*)m_command, L"MgSelectCommand.SetDistinct");
+ m_command->SetAlias(alias);
+}
+
+MgReader* MgSelectCommand::ExecuteJoined(MgStringCollection* idPropNames, bool bForceOneToOne)
+{
+ Ptr<MgReader> ret;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ FdoPtr<FdoIFeatureReader> fdoReader = m_command->Execute();
+ if (bForceOneToOne)
+ {
+ FdoPtr<FdoStringCollection> names = MgFeatureUtil::MgToFdoStringCollection(idPropNames, false);
+ FdoPtr<FdoIFeatureReader> forcedReader = new MgFdoForcedOneToOneFeatureReader(fdoReader, names);
+ ret = new MgdFeatureReader(m_connection, forcedReader);
+ }
+ else
+ {
+ ret = new MgdFeatureReader(m_connection, fdoReader);
+ }
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgSelectCommand.ExecuteJoined")
+
+ return ret.Detach();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,82 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MGSELECTCOMMAND_H_
+#define _MGSELECTCOMMAND_H_
+
+class MgFdoFeatureReader;
+class MgFdoReaderCollection;
+class MgFdoFilterCollection;
+
+class MgSelectCommand : public MgFeatureServiceCommand
+{
+ DECLARE_CLASSNAME(MgServerSqlProcessor)
+
+public:
+ MgSelectCommand(MgResourceIdentifier* resource);
+ virtual ~MgSelectCommand();
+
+ virtual FdoIdentifierCollection* GetPropertyNames();
+
+ virtual void SetDistinct( bool value );
+ virtual bool GetDistinct( );
+
+ virtual void SetFetchSize(FdoInt32 fetchSize);
+ virtual FdoInt32 GetFetchSize();
+
+ virtual FdoIdentifierCollection* GetOrdering();
+ virtual void SetOrderingOption( FdoOrderingOption option );
+ virtual FdoOrderingOption GetOrderingOption( );
+
+ virtual FdoIdentifierCollection* GetGrouping();
+ virtual void SetGroupingFilter( FdoFilter* filter );
+ virtual FdoFilter* GetGroupingFilter( );
+
+ virtual void SetFeatureClassName(FdoString* value);
+ virtual void SetFilter(FdoString* value);
+ virtual void SetFilter(FdoFilter* value);
+
+ virtual FdoFilter* GetFilter();
+
+ virtual MgReader* Execute();
+
+ virtual bool IsSupportedFunction(FdoFunction* fdoFunc);
+
+ virtual bool SupportsSelectGrouping();
+ virtual bool SupportsSelectOrdering();
+ virtual bool SupportsSelectDistinct();
+
+ virtual void Dispose()
+ {
+ delete this;
+ }
+
+ MgReader* ExecuteJoined(MgStringCollection* idPropNames, bool bForceOneToOne);
+ virtual FdoJoinCriteriaCollection* GetJoinCriteria();
+ virtual void SetAlias(FdoString* alias);
+
+private:
+ Ptr<MgFeatureConnection> m_connection;
+ STRING m_providerName;
+ FdoPtr<FdoISelect> m_command;
+
+ FdoPtr<FdoFilter> m_filter;
+
+ MgFdoFilterCollection* GetSubFilters();
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,2218 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "SelectFeatures.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/FeatureReader.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "FeatureServiceCommand.h"
+#include "SelectCommand.h"
+#include "SelectAggregateCommand.h"
+#include "Services/Feature/FeatureDistribution.h"
+#include "Services/Feature/GwsFeatureReader.h"
+#include "Services/Feature/GwsConnectionPool.h"
+#include "GwsCommonImp.h"
+#include "GwsMutableFeature.h"
+#include "GwsQuery.h"
+#include "FdoExpressionEngineCopyFilter.h"
+#include "Services/Feature/FeatureServiceCache.h"
+
+//Uncomment for extra console chatter to debug FDO joins
+//#define DEBUG_FDO_JOIN
+
+MgSelectFeatures::MgSelectFeatures()
+{
+ m_command = NULL;
+ m_options = NULL;
+ m_customPropertyFound = false;
+ m_customFunction = NULL;
+ m_customPropertyName = L"";
+ m_featureSourceCacheItem = NULL;
+
+ // Set a default join query batch size
+ m_nJoinQueryBatchSize = MgConfigProperties::DefaultFeatureServicePropertyJoinQueryBatchSize;
+
+ MgConfiguration* config = MgConfiguration::GetInstance();
+ if(config)
+ {
+ // Get the join batch size
+ config->GetIntValue(MgConfigProperties::FeatureServicePropertiesSection,
+ MgConfigProperties::FeatureServicePropertyJoinQueryBatchSize,
+ m_nJoinQueryBatchSize,
+ MgConfigProperties::DefaultFeatureServicePropertyJoinQueryBatchSize);
+ // Get data cache size
+ config->GetIntValue(MgConfigProperties::FeatureServicePropertiesSection,
+ MgConfigProperties::FeatureServicePropertyDataCacheSize,
+ m_nDataCacheSize,
+ MgConfigProperties::DefaultFeatureServicePropertyDataCacheSize);
+ }
+}
+
+MgSelectFeatures::~MgSelectFeatures()
+{
+}
+
+// Executes the select features command and serializes the reader
+MgReader* MgSelectFeatures::SelectFeatures(MgResourceIdentifier* resource,
+ CREFSTRING className,
+ MgFeatureQueryOptions* options,
+ bool executeSelectAggregate)
+{
+ Ptr<MgReader> mgReader;
+ bool isSelectAggregate = executeSelectAggregate;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ // Validate parameters
+ ValidateParam(resource,className);
+
+ // Retrieve the feature source
+ if (NULL == m_featureSourceCacheItem.p)
+ {
+ MgFeatureServiceCache* cacheManager = MgFeatureServiceCache::GetInstance();
+ m_featureSourceCacheItem = cacheManager->GetFeatureSource(resource);
+ }
+
+ // Set options (NULL is a valid value)
+ m_options = SAFE_ADDREF(options);
+ // Check if a feature join is to be performed by inspecting the resource for join properties
+ bool bFeatureJoinProperties = FindFeatureJoinProperties(resource, className);
+ // Check if a feature join is only a calculation
+ bool bFeatureCalculation = FindFeatureCalculation(resource, className);
+ //Test for the FDO join optimization, because performance is **substantially** better
+ bool bSupportsFdoJoin = SupportsFdoJoin(resource, className, isSelectAggregate);
+
+ // HACK: Sorry, we have to do this for now. Only SQLite provider satisifes the original
+ // FDO join optimization in both regular select and select aggregate modes
+ //
+ // SQL Server has problems in aggregate mode. So we'll say the FDO join optimization is
+ // not supported when this is in aggregate mode. This means the join is handled by the
+ // GWS query engine. SQL Server on SQL Server join will use the best algorithm (sort merge)
+ // as both sides are sortable so we won't suffer too much of a performance penalty.
+ if (isSelectAggregate)
+ {
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ const MdfModel::MdfString& providerName = featureSource->GetProvider();
+ if (providerName.find(L"OSGeo.SQLite") == MdfString::npos) //NOXLATE
+ bSupportsFdoJoin = false;
+ }
+
+#ifdef DEBUG_FDO_JOIN
+ STRING fsIdStr = resource->ToString();
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) Testing Feature Source (%W, %W) for FDO join optimization"), fsIdStr.c_str(), className.c_str()));
+#endif
+ if (!isSelectAggregate && bFeatureJoinProperties)
+ {
+ if (bSupportsFdoJoin)
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) Feature Source (%W) supports FDO join optimization"), fsIdStr.c_str()));
+#endif
+ m_command = MgFeatureServiceCommand::CreateCommand(resource, FdoCommandType_Select);
+ mgReader = SelectFdoJoin(resource, className, false);
+ }
+ else
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) Feature Source (%W) does not support the FDO join optimization. Using GwsQueryEngine"), fsIdStr.c_str()));
+#endif
+ // Get the FdoFilter from the options
+ // Create Command
+ CreateCommand(resource, isSelectAggregate);
+
+ // Apply options to FDO command
+ ApplyQueryOptions(isSelectAggregate);
+ FdoPtr<FdoFilter> filter = m_command->GetFilter();
+ // Perform feature join
+ mgReader = JoinFeatures(resource, className, filter);
+ }
+ }
+ else if (isSelectAggregate && bFeatureJoinProperties && bSupportsFdoJoin)
+ {
+ // NOTE: If this is FDO join capable, but contains functions over prefixed secondary properties
+ // We have to go through the GWS Query Engine because we haven't implemented reverse mapping
+ // of prefixed secondary class properties. Fortunately, the common case for this is distict value
+ // queries (eg. Generating themeable values), and GWS Query Engine is surprisingly performant in this case
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) Feature Source (%W) supports aggregate FDO join optimization"), fsIdStr.c_str()));
+#endif
+ // Perform the same select query as above, but route this through the FDO expression engine
+ // Slow maybe, but anything is faster than going via the GWS query engine.
+ m_command = MgFeatureServiceCommand::CreateCommand(resource, FdoCommandType_Select);
+ mgReader = SelectFdoJoin(resource, className, true);
+ }
+ else
+ {
+ // Custom function specified from Select command is not allowed
+ if (!isSelectAggregate && ContainsCustomFunction(options))
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgCustomFunctionNotSupported");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerSelectFeatures.SelectFeatures", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ // Custom function specified using SelectAggregate,
+ // we execute as standard Select command on single property
+ // then apply function on top of it.
+ bool useClassName = true;
+ if (isSelectAggregate && ContainsCustomFunction(options))
+ {
+ isSelectAggregate = false;
+ useClassName = false;
+ }
+ else if (bFeatureJoinProperties)
+ useClassName = false;
+
+ Ptr<MgReader> reader;
+
+ // Create Command
+ CreateCommand(resource, isSelectAggregate);
+
+ // Set the FeatureClass Name
+ if (useClassName && !bFeatureCalculation)
+ {
+ m_command->SetFeatureClassName((FdoString*)className.c_str());
+ }
+
+ // Apply options to FDO command
+ ApplyQueryOptions(isSelectAggregate);
+
+ // Check if the specified className is an extension (join) in the feature source
+ if (bFeatureJoinProperties && !bSupportsFdoJoin)
+ {
+ // 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<MgdGwsFeatureReader> gwsFeatureReader = JoinFeatures(resource, className, NULL);
+ try
+ {
+ // 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"MgSelectFeatures::SelectFeatures()",
+ __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
+
+ }
+
+ 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);
+
+ 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);
+ }
+
+ // 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();
+
+ // 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);
+ if(nPropStart != STRING::npos)
+ {
+ 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);
+ }
+
+ // 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);
+ else
+ m_command->SetFeatureClassName((FdoString*)className.c_str());
+
+ // If custom function is found, then validate that no more than one function/property is specified
+ ValidateConstraintsOnCustomFunctions();
+
+ // Execute the command
+ reader = m_command->Execute();
+
+ CHECKNULL((MgReader*)reader, L"MgServerSelectFeatures.SelectFeatures");
+
+ if (executeSelectAggregate && m_customPropertyFound)
+ {
+ mgReader = this->GetCustomReader(reader);
+ // Ticket 1051 MapGuide exhausts FDO connections during Fusion selection
+ // We are done with "reader" but Close() is not called during the release
+ // Close it here to avoid the connection leak
+ reader->Close();
+ }
+ else
+ {
+ // Increment the refcount as it will be decremented when we go out of try...catch
+ mgReader = SAFE_ADDREF((MgReader*)reader);
+ }
+ }
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerSelectFeatures.SelectFeatures")
+
+ return mgReader.Detach();
+}
+
+
+void MgSelectFeatures::ApplyQueryOptions(bool isSelectAggregate)
+{
+ CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyQueryOptions");
+
+ if (m_options != NULL)
+ {
+ ApplyClassProperties();
+ ApplyComputedProperties();
+ ApplyFilter();
+ // ApplySpatialFilter();
+ ApplyOrderingOptions();
+ ApplyAggregateOptions(isSelectAggregate);
+ ApplyFetchSize();
+ }
+}
+
+// ClassProperties
+void MgSelectFeatures::ApplyClassProperties()
+{
+ CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyClassProperties");
+ CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyClassProperties");
+
+ Ptr<MgStringCollection> properties = m_options->GetClassProperties();
+
+ if (properties == NULL)
+ return; // Nothing to do
+
+ INT32 cnt = properties->GetCount();
+ if (cnt <= 0)
+ return; // Nothing to do
+
+ //TODO: Need to check if FDO join optimization is supported, and whether this contains prefixed
+ //secondary properties.
+
+ FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
+ CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.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");
+
+ fic->Add(fdoIden);
+ }
+}
+
+
+// Computed properties
+void MgSelectFeatures::ApplyComputedProperties()
+{
+ CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyComputedProperties");
+ CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyComputedProperties");
+
+ Ptr<MgStringPropertyCollection> properties = m_options->GetComputedProperties();
+
+ if (properties == NULL)
+ return; // Nothing to do
+
+ INT32 cnt = properties->GetCount();
+ if (cnt <= 0)
+ return; // Nothing to do
+
+ //TODO: Need to check if FDO join optimization is supported, and whether this contains prefixed
+ //secondary properties in any expressions
+
+ // TODO: Add support for custom functions
+
+ for (INT32 i=0; i < cnt; i++)
+ {
+ STRING aliasName = properties->GetName(i);
+ STRING expression = properties->GetValue(i);
+
+ FdoString* str = (FdoString*)expression.c_str();
+ if (str != NULL)
+ {
+ FdoPtr<FdoExpression> expression = FdoExpression::Parse(str);
+ CHECKNULL((FdoExpression*)expression, L"MgServerSelectFeatures.ApplyComputedProperties");
+
+ bool udf = ContainsUdf(expression);
+ if (!udf)
+ {
+ AddFdoComputedProperty(aliasName, expression);
+ }
+ else
+ {
+ AddCustomComputedProperty(aliasName, expression);
+ }
+ }
+ }
+}
+
+//// Filter text
+//void MgSelectFeatures::ApplyFilter()
+//{
+// CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyFilter");
+// CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFilter");
+//
+// STRING filterText = m_options->GetFilter();
+// if (filterText.empty()) { return; } // Nothing to do
+//
+// m_command->SetFilter(filterText.c_str());
+//}
+
+// Fetch size
+void MgSelectFeatures::ApplyFetchSize()
+{
+ CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFetchSize");
+ if(m_options)
+ m_command->SetFetchSize(m_options->GetFetchSize());
+ else
+ m_command->SetFetchSize(m_nDataCacheSize);
+}
+
+// Spatial Filter
+void MgSelectFeatures::ApplyFilter()
+{
+ CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyFilter");
+ CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFilter");
+
+ FdoPtr<FdoFilter> regularFilter;
+ FdoPtr<FdoSpatialCondition> spatialFilter;
+ FdoPtr<FdoFilter> combineFilter;
+ FdoBinaryLogicalOperations bOper = FdoBinaryLogicalOperations_And;
+
+ // Build regular filter
+ STRING filterText = m_options->GetFilter();
+ if (!filterText.empty())
+ {
+ regularFilter = FdoFilter::Parse(filterText.c_str());
+ #ifdef _DEBUG
+ ACE_DEBUG((LM_ERROR, ACE_TEXT("FILTER(size=%d):\n%W\n\n"), filterText.length(), filterText.c_str()));
+ #endif
+ }
+
+ // Build spatial filter
+ bool isAnd = m_options->GetBinaryOperator();
+ Ptr<MgGeometry> geom = m_options->GetGeometry();
+ INT32 spatialOp = m_options->GetSpatialOperation();
+
+ STRING geomProp = m_options->GetGeometryProperty();
+
+ if (!isAnd) // Apply OR operator
+ {
+ bOper = FdoBinaryLogicalOperations_Or;
+ }
+
+ // Check whether we have valid geometric filter
+ if (!geomProp.empty() && (geom != NULL))
+ {
+ MgAgfReaderWriter agfWriter;
+
+ Ptr<MgByteReader> reader = agfWriter.Write(geom);
+ Ptr<MgByteSink> sink = new MgByteSink(reader);
+ Ptr<MgByte> bytes = sink->ToBuffer();
+
+ FdoByte* gisBytes = bytes->Bytes();
+ INT32 len = bytes->GetLength();
+
+ FdoPtr<FdoByteArray> byteArray = FdoByteArray::Create(gisBytes, (FdoInt32)len);
+
+ #ifdef _DEBUG
+ // Get the spatial filter geometry text
+ FdoPtr<FdoFgfGeometryFactory> geometryFactory = FdoFgfGeometryFactory::GetInstance();
+ if(geometryFactory)
+ {
+ FdoPtr<FdoIGeometry> geometry = geometryFactory->CreateGeometryFromFgf(byteArray);
+ STRING geomText = geometry->GetText();
+ ACE_DEBUG((LM_INFO, ACE_TEXT("(%t) SPATIAL FILTER:\n%W\n\n"), geomText.c_str()));
+ }
+ #endif
+
+ FdoPtr<FdoGeometryValue> geomValue = FdoGeometryValue::Create(byteArray);
+ if (geomValue != NULL)
+ {
+ FdoSpatialOperations fdoSpatialOp = MgFeatureUtil::GetFdoSpatialOperation(spatialOp);
+ spatialFilter = FdoSpatialCondition::Create((FdoString*)geomProp.c_str(), fdoSpatialOp, (FdoExpression*)geomValue);
+ }
+ }
+
+ // Determine which one to apply
+ if ((regularFilter != NULL) && (spatialFilter != NULL))
+ {
+ // Both filter exists, combine them
+ combineFilter = FdoFilter::Combine(regularFilter, bOper, spatialFilter);
+ }
+ else
+ {
+ if (regularFilter != NULL)
+ {
+ // Only regular filter exists
+ combineFilter = FDO_SAFE_ADDREF((FdoFilter*)regularFilter);
+ }
+ else if (spatialFilter != NULL)
+ {
+ // Only spatial filter exists
+ combineFilter = FDO_SAFE_ADDREF((FdoFilter*)spatialFilter);
+ }
+ }
+
+ // Apply the filter
+ if (combineFilter != NULL)
+ {
+ m_command->SetFilter(combineFilter);
+ }
+}
+
+// Ordering options
+void MgSelectFeatures::ApplyOrderingOptions()
+{
+ CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyOrderingOptions");
+ CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyOrderingOptions");
+
+ Ptr<MgStringCollection> properties = m_options->GetOrderingProperties();
+
+ if (properties == NULL)
+ return; // Nothing to do
+
+ INT32 cnt = properties->GetCount();
+ if (cnt <= 0)
+ return; // Nothing to do
+
+ // Ordering options are supplied but provider does not support it
+ if (!m_command->SupportsSelectOrdering())
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgOrderingOptionNotSupported");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerSelectFeatures.ApplyOrderingOptions", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ FdoPtr<FdoIdentifierCollection> fic = m_command->GetOrdering();
+ CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.ApplyOrderingOptions");
+
+ // Order option Asc or Desc (default is Asc)
+ FdoOrderingOption option = MgFeatureUtil::GetFdoOrderingOption(m_options->GetOrderOption());
+ m_command->SetOrderingOption(option);
+
+ for (INT32 i=0; i < cnt; i++)
+ {
+ STRING propertyName = properties->GetItem(i);
+
+ if (!propertyName.empty())
+ {
+ FdoPtr<FdoIdentifier> fdoIden = FdoIdentifier::Create((FdoString*)propertyName.c_str());
+ CHECKNULL((FdoIdentifier*)fdoIden, L"MgServerSelectFeatures.ApplyOrderingOptions");
+
+ fic->Add(fdoIden);
+ }
+ }
+}
+
+
+bool MgSelectFeatures::ContainsUdf(FdoExpression* expression)
+{
+ bool isUdf = false;
+ bool fdoSupported = false;
+
+ // Downcast to FdoFunction
+ FdoFunction* function = dynamic_cast<FdoFunction*>(expression);
+
+ // If we are unable to downcast, it means it is not a function, it is just
+ // an expression. We do not do anything with this. We just pass it to FDO
+ if (function != NULL)
+ {
+ if (m_command != NULL)
+ {
+ // Check if FDO supports this function, if so, let FDO handle it
+ fdoSupported = m_command->IsSupportedFunction(function);
+ }
+
+ if (!fdoSupported)
+ {
+ // If function is not supported, then check if it is a custom function.
+ isUdf = IsCustomFunction(function);
+ }
+ }
+
+ return isUdf;
+}
+
+
+bool MgSelectFeatures::IsCustomFunction(FdoFunction* fdoFunc)
+{
+ bool customFunc = false;
+
+ FdoString* funcNameAllowed = fdoFunc->GetName();
+ if (funcNameAllowed != NULL)
+ {
+ INT32 funcIndex = -1;
+ customFunc = MgFeatureUtil::FindCustomFunction(STRING(funcNameAllowed),funcIndex);
+ }
+
+ return customFunc;
+}
+
+void MgSelectFeatures::AddFdoComputedProperty(CREFSTRING aliasName, FdoExpression* expression)
+{
+ FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
+ CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.AddFdoComputedProperty");
+
+ FdoString* expName = aliasName.c_str();
+ if (expName != NULL)
+ {
+ FdoPtr<FdoComputedIdentifier> fdoIden = FdoComputedIdentifier::Create(expName, expression);
+ CHECKNULL((FdoComputedIdentifier*)fdoIden, L"MgServerSelectFeatures.AddFdoComputedProperty");
+
+ fic->Add(fdoIden);
+ }
+}
+
+void MgSelectFeatures::AddCustomComputedProperty(CREFSTRING aliasName, FdoExpression* expression)
+{
+ CHECKNULL((FdoExpression*)expression, L"MgServerSelectFeatures.AddCustomComputedProperty");
+
+ FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
+ CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.AddCustomComputedProperty");
+
+ // If property is already found, two custom properties are not supported and therefore throw exception
+ if (m_customPropertyFound)
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgOnlyOnePropertyAllowed");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerSelectFeatures.AddCustomComputedProperty", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ // Downcast to FdoFunction
+ FdoFunction* function = dynamic_cast<FdoFunction*>(expression);
+
+ if (function != NULL)
+ {
+ FdoString* expName = aliasName.c_str();
+ if (expName != NULL)
+ {
+ FdoPtr<FdoExpressionCollection> exprCol = function->GetArguments();
+ FdoInt32 cnt = exprCol->GetCount();
+ FdoPtr<FdoExpression> expr;
+ if (cnt > 0)
+ {
+ expr = exprCol->GetItem(0); // Property Name
+ }
+
+ // Just pass in the property name
+ // FdoPtr<FdoComputedIdentifier> fdoIden = FdoComputedIdentifier::Create(expName, expr);
+
+ // NOTE: Each provider has its own rule for supporting computed properties, select and select aggregate
+ // functionality. Therefore we just work with simple select command, fetch the property and do the needed
+ // calculations. Therefore, we are not adding them as computed properties.
+
+ FdoIdentifier* propName = dynamic_cast<FdoIdentifier*>(expr.p);
+
+ if (propName != NULL)
+ fic->Add(propName);
+
+ m_customPropertyName = aliasName;
+ m_customPropertyFound = true;
+ m_customFunction = FDO_SAFE_ADDREF(function);
+ }
+ }
+}
+
+void MgSelectFeatures::ValidateConstraintsOnCustomFunctions()
+{
+ // Custom function should only be allowed stand alone. This means, no other property along withit
+ // will be supported. Therefore
+ // 1. ClassProperties should be zero.
+ // 2. Computed properties (custom) should not be more than one
+ // 3. No GroupBy clause allowed
+ if (m_options != NULL)
+ {
+ Ptr<MgStringCollection> strCol = m_options->GetClassProperties();
+ INT32 classPropCnt = strCol->GetCount();
+
+ if (m_customPropertyFound)
+ {
+ if (classPropCnt > 0)
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgOnlyOnePropertyAllowed");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerSelectFeatures.ValidateConstraintsOnCustomFunctions",
+ __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+ MgFeatureUtil::ValidateCustomConstraints(m_customFunction);
+ }
+ }
+}
+
+
+void MgSelectFeatures::CreateCommand(MgResourceIdentifier* resource, bool isSelectAggregate)
+{
+ if (!isSelectAggregate)
+ {
+ m_command = MgFeatureServiceCommand::CreateCommand(resource, FdoCommandType_Select);
+ }
+ else
+ {
+ m_command = MgFeatureServiceCommand::CreateCommand(resource, FdoCommandType_SelectAggregates);
+ }
+ CHECKNULL((MgFeatureServiceCommand*)m_command, L"MgServerSelectFeatures.CreateCommand");
+}
+
+void MgSelectFeatures::ValidateParam(MgResourceIdentifier* resource, CREFSTRING className)
+{
+ // className and resource identifier can not be NULL
+ if (resource == NULL)
+ {
+ throw new MgNullArgumentException(L"MgSelectFeatures::ValidateParam()", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ if (className.empty())
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"2");
+ arguments.Add(MgResources::BlankArgument);
+
+ throw new MgInvalidArgumentException(L"MgSelectFeatures::ValidateParam()",
+ __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
+ }
+}
+
+void MgSelectFeatures::ApplyAggregateOptions(bool isSelectAggregate)
+{
+ // If not select aggregate, just return
+ if (!isSelectAggregate)
+ return;
+
+ // Downcast to see if it is an instance of MgFeatureAggregateOptions.
+ MgFeatureAggregateOptions* options = dynamic_cast<MgFeatureAggregateOptions*>((MgFeatureQueryOptions*)m_options);
+
+ // If it is not MgFeatureAggregateOptions, we simply return
+ if (options == NULL)
+ return;
+
+ STRING groupFilter = options->GetGroupFilter();
+ Ptr<MgStringCollection> strCol = options->GetGroupingProperties();
+ bool distinct = options->GetDistinct();
+
+ // Provider may throw exception if distinct operation is not supported.
+ // We delegate to provider instead of determining and throwing exception
+ // of our own
+ if (distinct)
+ {
+ // Set distinct requirements
+ ((MgFeatureServiceCommand*)m_command)->SetDistinct(distinct);
+ }
+
+ // Set all properties for grouping
+ ApplyFdoGroupingProperties(strCol);
+
+ // Set Grouping Filter
+ FdoPtr<FdoFilter> filter;
+ if (!groupFilter.empty())
+ {
+ filter = FdoFilter::Parse((FdoString*)groupFilter.c_str());
+ if (filter != NULL)
+ {
+ ((MgFeatureServiceCommand*)m_command)->SetGroupingFilter(filter);
+ }
+ }
+}
+
+void MgSelectFeatures::ApplyFdoGroupingProperties(MgStringCollection* propertyNames)
+{
+ CHECKNULL(m_options, L"MgServerSelectFeatures.ApplyFdoGroupingProperties");
+ CHECKNULL(m_command, L"MgServerSelectFeatures.ApplyFdoGroupingProperties");
+
+ Ptr<MgStringCollection> properties = SAFE_ADDREF(propertyNames);
+
+ if (properties == NULL)
+ return; // Nothing to do
+
+ INT32 cnt = properties->GetCount();
+ if (cnt <= 0)
+ return; // Nothing to do
+
+ // Grouping options are supplied but provider does not support it
+ if (!m_command->SupportsSelectGrouping())
+ {
+ STRING message = MgFeatureUtil::GetMessage(L"MgGroupingNotSupported");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerSelectFeatures.ApplyFdoGroupingProperties", __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ FdoPtr<FdoIdentifierCollection> fic = ((MgFeatureServiceCommand*)m_command)->GetGrouping();
+ CHECKNULL((FdoIdentifierCollection*)fic, L"MgServerSelectFeatures.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");
+
+ fic->Add(fdoIden);
+ }
+}
+
+// Check whether user is requesting custom operations
+bool MgSelectFeatures::ContainsCustomFunction(MgFeatureQueryOptions* options)
+{
+ bool hasCustomFunction = false;
+
+ if (options == NULL)
+ return false;
+
+ Ptr<MgStringPropertyCollection> properties = options->GetComputedProperties();
+
+ if (properties == NULL)
+ return false; // Nothing to do
+
+ INT32 cnt = properties->GetCount();
+ if (cnt <= 0)
+ return false; // Nothing to do
+
+ for (INT32 i=0; i < cnt; i++)
+ {
+ STRING aliasName = properties->GetName(i);
+ STRING expression = properties->GetValue(i);
+
+ FdoString* str = (FdoString*)expression.c_str();
+ if (str != NULL)
+ {
+ FdoPtr<FdoExpression> expression = FdoExpression::Parse(str);
+ CHECKNULL((FdoExpression*)expression, L"MgServerSelectFeatures.ContainsCustomFunction");
+
+ hasCustomFunction = ContainsUdf(expression);
+ }
+ }
+
+ if (hasCustomFunction && (cnt != 1))
+ {
+ // Only one custom function with no property is allowed
+ STRING message = MgFeatureUtil::GetMessage(L"MgOnlyOnePropertyAllowed");
+
+ MgStringCollection arguments;
+ arguments.Add(message);
+ throw new MgFeatureServiceException(L"MgServerSelectFeatures.ContainsCustomFunction",
+ __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ return hasCustomFunction;
+}
+
+// Convert reader into a custom MgDataReader
+MgReader* MgSelectFeatures::GetCustomReader(MgReader* reader)
+{
+ Ptr<MgReader> distReader;
+ if (m_customPropertyFound)
+ {
+ Ptr<MgFeatureDistribution> featureDist =
+ MgFeatureDistribution::CreateDistributionFunction(reader, m_customFunction, m_customPropertyName);
+
+ distReader = featureDist->Execute();
+ }
+
+ return distReader.Detach();
+}
+
+// Look for extension which have calculations but no joins
+bool MgSelectFeatures::FindFeatureCalculation(MgResourceIdentifier* resourceId, CREFSTRING extensionName)
+{
+ bool bCalculationExists = false;
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.FindFeatureCalculation");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.FindFeatureCalculation");
+
+ for (int i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgServerSelectFeatures.FindFeatureCalculation");
+ STRING name = (STRING)extension->GetName();
+
+ STRING parsedSchemaName, parsedExtensionName;
+ MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
+
+ if (parsedExtensionName != name)
+ {
+ continue;
+ }
+ else
+ {
+ CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
+ // we don't have joins but we have calculations
+ bCalculationExists = (calcProps != NULL && calcProps->GetCount() != 0);
+ break;
+ }
+ }
+
+ return bCalculationExists;
+}
+
+// Look for extension (feature join) properties in the feature source document
+bool MgSelectFeatures::FindFeatureJoinProperties(MgResourceIdentifier* resourceId, CREFSTRING extensionName)
+{
+ bool bJoinPropertiesExists = false;
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.FindFeatureJoinProperties");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.FindFeatureJoinProperties");
+
+ for (int i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgServerSelectFeatures.FindFeatureJoinProperties");
+ STRING name = (STRING)extension->GetName();
+
+ STRING parsedSchemaName, parsedExtensionName;
+ MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
+
+ if (parsedExtensionName != name)
+ {
+ continue;
+ }
+ else
+ {
+ AttributeRelateCollection* relates = extension->GetAttributeRelates();
+ bJoinPropertiesExists = (relates != NULL && relates->GetCount() != 0);
+ break;
+ }
+ }
+
+ return bJoinPropertiesExists;
+}
+
+void MgSelectFeatures::UpdateCommandOnJoinCalculation(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName)
+{
+ MG_FEATURE_SERVICE_TRY()
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation");
+
+ for (int i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation");
+ STRING name = (STRING)extension->GetName();
+
+ STRING parsedSchemaName, parsedExtensionName;
+ ParseQualifiedClassNameForCalculation(extension, extensionName, parsedSchemaName, parsedExtensionName);
+
+ if (parsedExtensionName != name)
+ {
+ continue;
+ }
+ else
+ {
+ CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
+ if (calcProps == NULL || calcProps->GetCount() == 0)
+ break;
+ FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
+ for (int idx = 0; idx < calcProps->GetCount(); idx++)
+ {
+ CalculatedProperty* calcProp = calcProps->GetAt(idx);
+ FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
+ FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
+ idList->Add(idfCalc);
+ }
+ FdoPtr<FdoFilter> filter = m_command->GetFilter();
+ if (filter != NULL)
+ {
+ FdoPtr<FdoFilter> newFilter = FdoExpressionEngineCopyFilter::Copy(filter, idList);
+ m_command->SetFilter(newFilter);
+ }
+
+ FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
+ if (fic->GetCount() != 0)
+ {
+ // replace calculated properties provided as identifiers to computed identifiers
+ for (int idx = 0; idx < calcProps->GetCount(); idx++)
+ {
+ CalculatedProperty* calcProp = calcProps->GetAt(idx);
+ FdoPtr<FdoIdentifier> idf = fic->FindItem(calcProp->GetName().c_str());
+ if (idf != NULL)
+ {
+ FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(idf->GetName()));
+ FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
+ FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
+
+ int idfIndex = fic->IndexOf(idf);
+ FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(idf->GetName(), expandedExpression);
+ fic->SetItem(idfIndex, newIdf);
+ }
+ }
+ }
+ break;
+ }
+ }
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgServerSelectFeatures.UpdateCommandOnJoinCalculation")
+}
+
+void MgSelectFeatures::UpdateCommandOnCalculation(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName)
+{
+ MG_FEATURE_SERVICE_TRY()
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.UpdateCommandOnCalculation");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.UpdateCommandOnCalculation");
+
+ for (int i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgServerSelectFeatures.UpdateCommandOnCalculation");
+ STRING name = (STRING)extension->GetName();
+
+ STRING parsedSchemaName, parsedExtensionName;
+ ParseQualifiedClassNameForCalculation(extension, extensionName, parsedSchemaName, parsedExtensionName);
+
+ if (parsedExtensionName != name)
+ {
+ continue;
+ }
+ else
+ {
+ m_command->SetFeatureClassName(extension->GetFeatureClass().c_str());
+ CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
+ if (calcProps == NULL || calcProps->GetCount() == 0)
+ break;
+ FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
+ for (int idx = 0; idx < calcProps->GetCount(); idx++)
+ {
+ CalculatedProperty* calcProp = calcProps->GetAt(idx);
+ FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
+ FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
+ idList->Add(idfCalc);
+ }
+ FdoPtr<FdoFilter> filter = m_command->GetFilter();
+ if (filter != NULL)
+ {
+ FdoPtr<FdoFilter> newFilter = FdoExpressionEngineCopyFilter::Copy(filter, idList);
+ m_command->SetFilter(newFilter);
+ }
+
+ FdoPtr<FdoIdentifierCollection> fic = m_command->GetPropertyNames();
+ bool addAllProps = (fic->GetCount() == 0);
+ for (int idx = 0; idx < calcProps->GetCount(); idx++)
+ {
+ CalculatedProperty* calcProp = calcProps->GetAt(idx);
+ FdoPtr<FdoIdentifier> idf = fic->FindItem(calcProp->GetName().c_str());
+ if (idf != NULL)
+ {
+ // replace calculated properties provided as identifiers to computed identifiers
+ FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(idf->GetName()));
+ FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
+ FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
+
+ int idfIndex = fic->IndexOf(idf);
+ FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(idf->GetName(), expandedExpression);
+ fic->SetItem(idfIndex, newIdf);
+ }
+ else
+ {
+ if (addAllProps)
+ {
+ FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(calcProp->GetName().c_str()));
+ FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
+ FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
+
+ FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expandedExpression);
+ fic->Add(newIdf);
+ }
+ }
+ if (addAllProps)
+ {
+ Ptr<MgFeatureConnection> fcConnection = new MgFeatureConnection(featureSourceId);
+ if ((NULL != fcConnection.p) && ( fcConnection->IsConnectionOpen() ))
+ {
+ // The reference to the FDO connection from the MgFeatureConnection object must be cleaned up before the parent object
+ // otherwise it leaves the FDO connection marked as still in use.
+ FdoPtr<FdoIConnection> conn = fcConnection->GetConnection();
+ FdoPtr<FdoIDescribeSchema> descSchema = (FdoIDescribeSchema *) conn->CreateCommand (FdoCommandType_DescribeSchema);
+
+ STRING fullClassName = extension->GetFeatureClass();
+ STRING schemaName, className;
+ MgUtil::ParseQualifiedClassName(fullClassName, schemaName, className);
+
+ if (!parsedSchemaName.empty())
+ {
+ descSchema->SetSchemaName(parsedSchemaName.c_str());
+ }
+
+ if (!className.empty())
+ {
+ FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
+
+ classNames->Add(className.c_str());
+ descSchema->SetClassNames(classNames.p);
+ }
+
+ FdoPtr <FdoFeatureSchemaCollection> schemas = (FdoFeatureSchemaCollection *) descSchema->Execute ();
+ FdoPtr<FdoFeatureSchema> schema = (FdoFeatureSchema *)schemas->GetItem (parsedSchemaName.c_str());
+ FdoPtr<FdoClassCollection> classes = schema->GetClasses();
+
+ FdoPtr<FdoClassDefinition> activeClass = classes->GetItem(className.c_str());
+ FdoPtr<FdoPropertyDefinitionCollection> properties = activeClass->GetProperties();
+ for(int i = 0; i < properties->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition> activeProperty = properties->GetItem(i);
+ FdoPtr<FdoIdentifier> idf = fic->FindItem(activeProperty->GetName());
+ if (idf == NULL)
+ {
+ idf = FdoIdentifier::Create(activeProperty->GetName());
+ fic->Add(idf);
+ }
+ }
+ FdoPtr<FdoReadOnlyPropertyDefinitionCollection> baseProps = activeClass->GetBaseProperties();
+ if (baseProps != NULL)
+ {
+ for(int i = 0; i < baseProps->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition>prop = baseProps->GetItem(i);
+ if( prop->GetIsSystem() )
+ continue;
+ fic->Add( FdoPtr<FdoIdentifier>(FdoIdentifier::Create( prop->GetName() ) ) );
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceId, L"MgServerSelectFeatures.UpdateCommandOnCalculation")
+}
+
+MgdGwsFeatureReader* MgSelectFeatures::JoinFeatures(MgResourceIdentifier* featureSourceIdentifier, CREFSTRING extensionName, FdoFilter* filter)
+{
+ Ptr<MgdGwsFeatureReader> gwsFeatureReader;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ FdoPtr<IGWSQueryDefinition> qd;
+ FdoPtr<MgGwsConnectionPool> pool = MgGwsConnectionPool::Create();
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.JoinFeatures");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.JoinFeatures");
+
+ for (int i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgServerSelectFeatures.JoinFeatures");
+ STRING name = (STRING)extension->GetName();
+
+ STRING parsedSchemaName, parsedExtensionName;
+ MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
+
+ if (parsedExtensionName != name)
+ {
+ continue;
+ }
+ else
+ {
+ // Establish connection to provider for primary feature source
+ STRING primaryConnectionName;
+ MgUtil::GenerateUuid(primaryConnectionName);
+ Ptr<MgFeatureConnection> msfcLeft = new MgFeatureConnection(featureSourceIdentifier);
+ if ((NULL != msfcLeft.p) && ( msfcLeft->IsConnectionOpen() ))
+ {
+ pool->AddConnection(primaryConnectionName.c_str(), msfcLeft);
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgServerSelectFeatures.JoinFeatures",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ // Retrieve the primary feature class
+ STRING featureClass = (STRING)extension->GetFeatureClass();
+
+ // Parse the qualifed classname
+ STRING primaryFsSchema, primaryFsClassName;
+ MgUtil::ParseQualifiedClassName(featureClass, primaryFsSchema, primaryFsClassName);
+
+ // Create primary query definition
+ FdoPtr<FdoIdentifierCollection> lsellist;
+ FdoPtr<FdoFilter> lfilter;
+
+ // in case we have calculations we must add all properties + computed properties to the selection list
+ MdfModel::CalculatedPropertyCollection* calcProps = extension->GetCalculatedProperties();
+ if (calcProps != NULL && calcProps->GetCount() != 0)
+ {
+ FdoPtr<FdoIdentifierCollection> idList = FdoIdentifierCollection::Create();
+ for (int idx = 0; idx < calcProps->GetCount(); idx++)
+ {
+ CalculatedProperty* calcProp = calcProps->GetAt(idx);
+ FdoPtr<FdoExpression> expressionCalc = FdoExpression::Parse(calcProp->GetExpression().c_str());
+ FdoPtr<FdoComputedIdentifier> idfCalc = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expressionCalc);
+ idList->Add(idfCalc);
+ }
+ lsellist = FdoIdentifierCollection::Create();
+ for (int idx = 0; idx < calcProps->GetCount(); idx++)
+ {
+ CalculatedProperty* calcProp = calcProps->GetAt(idx);
+ FdoPtr<FdoComputedIdentifier> idfCalc = static_cast<FdoComputedIdentifier*>(idList->GetItem(calcProp->GetName().c_str()));
+ FdoPtr<FdoExpression> expressionCalc = idfCalc->GetExpression();
+ FdoPtr<FdoExpression> expandedExpression = FdoExpressionEngineCopyFilter::Copy(expressionCalc, idList);
+
+ FdoPtr<FdoComputedIdentifier> newIdf = FdoComputedIdentifier::Create(calcProp->GetName().c_str(), expandedExpression);
+ lsellist->Add(newIdf);
+ }
+ FdoPtr<FdoIConnection> conn = msfcLeft->GetConnection();
+ FdoPtr<FdoIDescribeSchema> descSchema = (FdoIDescribeSchema *) conn->CreateCommand (FdoCommandType_DescribeSchema);
+
+ STRING fullClassName = extension->GetFeatureClass();
+ STRING schemaName, className;
+ MgUtil::ParseQualifiedClassName(fullClassName, schemaName, className);
+
+ if (!parsedSchemaName.empty())
+ {
+ descSchema->SetSchemaName(parsedSchemaName.c_str());
+ }
+
+ if (!className.empty())
+ {
+ FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
+
+ classNames->Add(className.c_str());
+ descSchema->SetClassNames(classNames.p);
+ }
+
+ FdoPtr <FdoFeatureSchemaCollection> schemas = (FdoFeatureSchemaCollection *) descSchema->Execute ();
+ FdoPtr<FdoFeatureSchema> schema = (FdoFeatureSchema *)schemas->GetItem (parsedSchemaName.c_str());
+ FdoPtr<FdoClassCollection> classes = schema->GetClasses();
+
+ FdoPtr<FdoClassDefinition> activeClass = classes->GetItem(className.c_str());
+ FdoPtr<FdoPropertyDefinitionCollection> properties = activeClass->GetProperties();
+ for(int i = 0; i < properties->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition> activeProperty = properties->GetItem(i);
+ FdoPtr<FdoIdentifier> idf = FdoIdentifier::Create(activeProperty->GetName());
+ lsellist->Add(idf);
+ }
+ FdoPtr<FdoReadOnlyPropertyDefinitionCollection> baseProps = activeClass->GetBaseProperties();
+ if (baseProps != NULL)
+ {
+ for(int i = 0; i < baseProps->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition>prop = baseProps->GetItem(i);
+ if( prop->GetIsSystem() )
+ continue;
+ lsellist->Add( FdoPtr<FdoIdentifier>(FdoIdentifier::Create( prop->GetName() ) ) );
+ }
+ }
+ }
+
+ FdoPtr<IGWSQueryDefinition> lqd = IGWSFeatureQueryDefinition::Create(
+ lsellist,
+ GWSQualifiedName(primaryConnectionName.c_str(), primaryFsSchema.c_str(), primaryFsClassName.c_str()),
+ lfilter);
+ CHECKNULL(lqd, L"MgServerSelectFeatures.JoinFeatures");
+ qd = lqd;
+
+ IGWSJoinQueryDefinition* jqd = NULL;
+
+ MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
+ CHECKNULL(attributeRelates, L"MgServerSelectFeatures.JoinFeatures");
+
+ bool bForceOneToOne = true;
+ Ptr<MgStringCollection> attributeNameDelimiters = new MgStringCollection();
+
+ //Store all the secondary's name, and if the filter property doesn't contain secondary's name,
+ //it applies only to the primary.
+ Ptr<MgStringCollection> secondaryNames = new MgStringCollection();
+
+ // For each join (attributeRelate) to a secondary source need to do the following
+ for (int attributeRelateIndex = 0; attributeRelateIndex < attributeRelates->GetCount(); attributeRelateIndex++)
+ {
+ MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(attributeRelateIndex);
+ CHECKNULL(attributeRelate, L"MgServerSelectFeatures.JoinFeatures");
+
+ // Get the secondary resource id
+ STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
+
+ // Get the name for the join relationship
+ STRING attributeRelateName = (STRING)attributeRelate->GetName();
+ STRING secondaryConnectionName = attributeRelateName;
+
+ if(!secondaryNames->Contains(attributeRelateName))
+ secondaryNames->Add(attributeRelateName);
+
+ // Get the RelateType (join type). Default is Left Outer join.
+ MdfModel::AttributeRelate::RelateType relateType = attributeRelate->GetRelateType();
+
+ // Get the ForceOneToOne field, which specifies if multiple matching secondary features
+ // are retrieved via a 1-to-1 or 1-to-many relationship. Default is 1-to-1 relationship.
+ bool forceOneToOne = attributeRelate->GetForceOneToOne();
+ // If there is at least one relation is defined as one-to-many, then the one-to-many result will apply to all join results.
+ if (!forceOneToOne)
+ {
+ bForceOneToOne = false;
+ }
+
+ // Get the AttributeNameDelimiter field, which specifies the delimiter between the JoinName (attribute relate name)
+ // and the property name for an extended property. Default delimiter is "" (blank).
+ STRING attributeNameDelimiter = (STRING)attributeRelate->GetAttributeNameDelimiter();
+ attributeNameDelimiters->Add(attributeNameDelimiter);
+
+ // Establish connection to provider for secondary feature source
+ Ptr<MgResourceIdentifier> secondaryFeatureSource = new MgResourceIdentifier(secondaryResourceId);
+
+ if (NULL != secondaryFeatureSource)
+ {
+ Ptr<MgFeatureConnection> msfcRight = new MgFeatureConnection(secondaryFeatureSource);
+ if ((NULL != msfcRight.p) && ( msfcRight->IsConnectionOpen() ))
+ {
+ pool->AddConnection(secondaryConnectionName.c_str(), msfcRight);
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgServerSelectFeatures.JoinFeatures",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ }
+
+ // Get the secondary featureClassName (qualified className)
+ STRING secondaryClassName = (STRING)attributeRelate->GetAttributeClass();
+
+ // Parse the qualified classname
+ STRING secondaryFsSchema, secondaryFsClassName;
+ MgUtil::ParseQualifiedClassName(secondaryClassName, secondaryFsSchema, secondaryFsClassName);
+
+ // Create secondary query definition
+ FdoPtr<FdoIdentifierCollection> rsellist;
+ FdoPtr<FdoFilter> rfilter;
+
+ FdoPtr<IGWSQueryDefinition> rqd = IGWSFeatureQueryDefinition::Create(
+ rsellist,
+ GWSQualifiedName(secondaryConnectionName.c_str(), secondaryFsSchema.c_str(), secondaryFsClassName.c_str()),
+ rfilter);
+ CHECKNULL(rqd, L"MgServerSelectFeatures.JoinFeatures");
+
+ // Get Join Attributes
+ FdoPtr<FdoStringCollection> lattrs = FdoStringCollection::Create();
+ FdoPtr<FdoStringCollection> rattrs = FdoStringCollection::Create();
+
+ // Determine the number of RelateProperties (attributes)
+ MdfModel::RelatePropertyCollection* relateProperties = attributeRelate->GetRelateProperties();
+ CHECKNULL(relateProperties, L"MgServerSelectFeatures.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");
+
+ // Get the FeatureClassProperty (primary attribute)
+ STRING primaryAttribute = (STRING)relateProperty->GetFeatureClassProperty();
+
+ // Add to the primary attribute String collection
+ lattrs->Add(primaryAttribute.c_str());
+
+ // Get the AttributeClassProperty (secondary attribute)
+ STRING secondaryAttribute = (STRING)relateProperty->GetAttributeClassProperty();
+
+ // Add to the secondary attribute String collection
+ rattrs->Add(secondaryAttribute.c_str());
+ }
+
+ // Create the QueryDefinition
+ if (NULL != rqd)
+ {
+ FdoString* joinName = attributeRelateName.c_str();
+ FdoString* joinDelimiter = L".";
+ if (MdfModel::AttributeRelate::Inner == relateType)
+ {
+ jqd = IGWSEqualJoinQueryDefinition::Create(joinName, joinDelimiter, bForceOneToOne, lqd, rqd, lattrs, rattrs);
+ }
+ else // if (RelateType::LeftOuter == relateType)
+ {
+ jqd = IGWSLeftJoinQueryDefinition::Create(joinName, joinDelimiter, bForceOneToOne, lqd, rqd, lattrs, rattrs);
+ }
+ lqd = jqd;
+ }
+
+ } // Repeat for each secondary source
+ qd = lqd;
+
+ FdoPtr<IGWSQuery> query = IGWSQuery::Create(pool, qd, NULL);
+ FdoPtr<IGWSFeatureIterator> iter;
+ FdoPtr<IGWSFeatureIterator> iterCopy;
+
+ // Set batch size as it may be needed
+ CGwsBatchSortedBlockJoinQueryResults::sm_nBatchSize = m_nJoinQueryBatchSize;
+
+ // Prepare and Execute Query
+ query->Prepare();
+
+ // Search the filter to see if it contains the extension name
+ // If the extension name is not found it means that the filter involves attribute(s) only from the primary
+ if(NULL != filter)
+ {
+ FdoString* filterText = filter->ToString();
+ if(NULL != filterText)
+ {
+ bool match = false;
+ for(int i = 0; i < secondaryNames->GetCount(); i ++)
+ {
+ STRING secondaryName = secondaryNames->GetItem(i);
+ if(NULL != wcsstr(filterText, secondaryName.c_str()))
+ {
+ match = true;
+ break;
+ }
+ }
+ if(!match)
+ {
+ // Add the filter to the query because it only applies to the primary
+ query->SetFilter(filter);
+ }
+ }
+ }
+
+ // Execute the query
+ query->Execute(&iter, true);
+ query->Execute(&iterCopy, true);
+
+ FdoPtr<FdoStringCollection> fsNames = qd->FeatureSourceNames();
+
+ gwsFeatureReader = new MgdGwsFeatureReader(pool, iter, iterCopy, parsedExtensionName, fsNames, bForceOneToOne, attributeNameDelimiters);
+ gwsFeatureReader->SetFilter(filter);
+ break;
+ }
+ }
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(featureSourceIdentifier, L"MgServerSelectFeatures.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.
+ // We want to avoid a deadlock of the connection :)
+ gwsFeatureReader->OwnsConnections();
+
+ return gwsFeatureReader.Detach();
+}
+
+void MgSelectFeatures::ParseQualifiedClassNameForCalculation(MdfModel::Extension* extension, CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className)
+{
+ CHECKNULL(extension, L"MgServerSelectFeatures.ParseQualifiedClassNameForCalculation");
+
+ MgUtil::ParseQualifiedClassName(qualifiedClassName, schemaName, className);
+
+ if (schemaName.empty())
+ {
+ STRING dummyStr;
+
+ MgUtil::ParseQualifiedClassName(extension->GetFeatureClass(), schemaName, dummyStr);
+ }
+}
+
+MgResourceIdentifier* MgSelectFeatures::GetSecondaryResourceIdentifier(MgResourceIdentifier* primResId, CREFSTRING extensionName, CREFSTRING relationName)
+{
+ Ptr<MgResourceIdentifier> secResId;
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+
+ for (int i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* extension = extensions->GetAt(i);
+ CHECKNULL(extension, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+
+ // Get the extension name
+ STRING name = (STRING)extension->GetName();
+
+ STRING parsedSchemaName, parsedExtensionName;
+ MgUtil::ParseQualifiedClassName(extensionName, parsedSchemaName, parsedExtensionName);
+
+ if (parsedExtensionName != name)
+ {
+ continue;
+ }
+ else
+ {
+ // Determine the number of secondary sources (AttributeRelates)
+ MdfModel::AttributeRelateCollection* attributeRelates = extension->GetAttributeRelates();
+ CHECKNULL(attributeRelates, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+ int nAttributeRelateCount = attributeRelates->GetCount();
+
+ // Find the specified relation name
+ {
+ for (int attributeRelateIndex = 0; attributeRelateIndex < nAttributeRelateCount; attributeRelateIndex++)
+ {
+ MdfModel::AttributeRelate* attributeRelate = attributeRelates->GetAt(attributeRelateIndex);
+ CHECKNULL(attributeRelate, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
+
+ // Get the name for the join relationship
+ STRING attributeRelateName = (STRING)attributeRelate->GetName();
+
+ if (attributeRelateName != relationName)
+ {
+ continue;
+ }
+ else
+ {
+ // Get the secondary resource id
+ STRING secondaryResourceId = (STRING)attributeRelate->GetResourceId();
+ secResId = new MgResourceIdentifier(secondaryResourceId);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return secResId.Detach();
+}
+
+bool MgSelectFeatures::SupportsFdoJoin(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName, bool isAggregate)
+{
+ bool bSupported = false;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ //This could be qualified, so parse it to be sure
+ STRING schemaName;
+ STRING extName;
+ MgUtil::ParseQualifiedClassName(extensionName, schemaName, extName);
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.SupportsFdoJoin");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.SupportsFdoJoin");
+
+ MdfModel::Extension* extension = NULL;
+ for (INT32 i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* ext = extensions->GetAt(i);
+ if (ext->GetName() == extName)
+ {
+ extension = ext;
+ break;
+ }
+ }
+
+ if (NULL == extension) //Extension in question not found
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] Could not find extension named: %W"), extensionName.c_str()));
+#endif
+ return false;
+ }
+
+ Ptr<MgFeatureConnection> conn = new MgFeatureConnection(featureSourceId);
+ {
+ if (!conn->IsConnectionOpen())
+ {
+ throw new MgConnectionFailedException(L"MgServerSelectFeatures.SupportsFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ FdoPtr<FdoIConnection> fdoConn = conn->GetConnection();
+ FdoPtr<FdoIConnectionCapabilities> connCaps = fdoConn->GetConnectionCapabilities();
+
+ MdfModel::AttributeRelateCollection* relates = extension->GetAttributeRelates();
+
+ //Get the easy checks out of the way
+ if (!connCaps->SupportsJoins())
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] The provider does not support the FDO join APIs")));
+#endif
+ return false;
+ }
+
+ FdoJoinType jtypes = (FdoJoinType)connCaps->GetJoinTypes();
+
+ //Now ascertain if all participating feature classes originate from the same feature source
+
+ //We've yet to figure out chained joins. TODO: Revisit later
+ if (relates->GetCount() > 1)
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] Chained/Multiple FDO Joins not supported yet")));
+#endif
+ return false;
+ }
+
+ //Need to check the filter here to see if it involves secondary class properties and/or
+ //expressions involving such properties. We don't support this yet
+ if (m_options != NULL && relates->GetCount())
+ {
+ MdfModel::AttributeRelate* relate = relates->GetAt(0);
+ STRING filterText = m_options->GetFilter();
+ STRING qualifiedName = relate->GetAttributeClass();
+ STRING schemaName;
+ STRING clsName;
+ MgUtil::ParseQualifiedClassName(qualifiedName, schemaName, clsName);
+ if (FilterContainsSecondaryProperties(featureSourceId, filterText, schemaName, clsName, relate->GetName()))
+ {
+ #ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] Filter contains secondary class properties")));
+ #endif
+ return false;
+ }
+ }
+
+ for (INT32 i = 0; i < relates->GetCount(); i++)
+ {
+ MdfModel::AttributeRelate* relate = relates->GetAt(i);
+ const MdfModel::MdfString& fsId = relate->GetResourceId();
+
+ //Different feature sources
+ if (featureSourceId->ToString() != fsId)
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] The extension does not join with another class from the same data store")));
+#endif
+ return false;
+ }
+
+ //TODO: Review when we lift the one join limit
+ if (NULL != (MgFeatureQueryOptions*)m_options)
+ {
+ //Is this costly? Should we cache it?
+ //FdoPtr<FdoFunctionDefinitionCollection> functions = FdoExpressionEngine::GetStandardFunctions();
+ Ptr<MgStringPropertyCollection> expressions = m_options->GetComputedProperties();
+ for (INT32 i = 0; i < expressions->GetCount(); i++)
+ {
+ Ptr<MgStringProperty> compProp = expressions->GetItem(i);
+ STRING exprText = compProp->GetValue();
+ FdoPtr<FdoExpression> fdoExpr = FdoExpression::Parse(exprText.c_str());
+
+ if (fdoExpr->GetExpressionType() == FdoExpressionItemType_Function)
+ {
+ FdoFunction* func = static_cast<FdoFunction*>(fdoExpr.p);
+ FdoString* funcName = func->GetName();
+
+ // We don't support functions on prefixed secondary properties (yet)
+ // so we have to check these functions to ensure they are only operating on the
+ // primary side properties
+ STRING primarySchemaName;
+ STRING primaryClassName;
+ MgUtil::ParseQualifiedClassName(extension->GetFeatureClass(), primarySchemaName, primaryClassName);
+ bool bValidFunction = IsFunctionOnPrimaryProperty(func, fdoConn, primarySchemaName, primaryClassName);
+ if (!bValidFunction)
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] FDO Function %W contains a non-primary or unrecognised identifier"), funcName));
+#endif
+ return false;
+ }
+ }
+ }
+ }
+
+ MdfModel::RelatePropertyCollection* relProps = relate->GetRelateProperties();
+
+ //Check if the join type is supported. Given FDO exposes more join types than
+ //the ones specified here, the chances are real good that we'll have a match
+ MdfModel::AttributeRelate::RelateType rtype = relate->GetRelateType();
+ switch(rtype)
+ {
+ case MdfModel::AttributeRelate::Inner:
+ if ((jtypes & FdoJoinType_Inner) != FdoJoinType_Inner)
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] The provider does not support Inner Join")));
+#endif
+ return false;
+ }
+ break;
+ case MdfModel::AttributeRelate::LeftOuter:
+ if ((jtypes & FdoJoinType_LeftOuter) != FdoJoinType_LeftOuter)
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] The provider does not support Left Outer Join")));
+#endif
+ return false;
+ }
+ break;
+ case MdfModel::AttributeRelate::RightOuter:
+ if ((jtypes & FdoJoinType_RightOuter) != FdoJoinType_RightOuter)
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] The provider does not support Right Outer Join")));
+#endif
+ return false;
+ }
+ break;
+ default:
+ {
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] The join type is not recognised")));
+#endif
+ return false;
+ }
+ }
+ }
+
+ //Still here? You pass the test
+ bSupported = true;
+ }
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerSelectFeatures.SupportsFdoJoin")
+
+ return bSupported;
+}
+
+bool MgSelectFeatures::IsFunctionOnPrimaryProperty(FdoFunction* function, FdoIConnection* fdoConn, CREFSTRING schemaName, CREFSTRING className)
+{
+ FdoPtr<FdoIdentifierCollection> identifiers = MgFeatureUtil::ExtractIdentifiers(function);
+ if (identifiers->GetCount() == 0)
+ return true; //Inconsequential
+
+ FdoPtr<FdoIDescribeSchema> descSchema = dynamic_cast<FdoIDescribeSchema*>(fdoConn->CreateCommand(FdoCommandType_DescribeSchema));
+ CHECKNULL((FdoIDescribeSchema*)descSchema, L"MgServerSelectFeatures.SelectFdoJoin");
+
+ if (!schemaName.empty())
+ {
+ descSchema->SetSchemaName(schemaName.c_str());
+ }
+ if (!className.empty())
+ {
+ FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
+ classNames->Add(className.c_str());
+ descSchema->SetClassNames(classNames);
+ }
+
+ FdoPtr<FdoClassDefinition> classDef;
+ FdoPtr<FdoFeatureSchemaCollection> schemas = descSchema->Execute();
+ for (FdoInt32 i = 0; i < schemas->GetCount(); i++)
+ {
+ FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(i);
+ if (wcscmp(schema->GetName(), schemaName.c_str()) == 0)
+ {
+ FdoPtr<FdoClassCollection> classes = schema->GetClasses();
+ for (FdoInt32 j = 0; j < classes->GetCount(); j++)
+ {
+ FdoPtr<FdoClassDefinition> klassDef = classes->GetItem(j);
+ if (wcscmp(klassDef->GetName(), className.c_str()) == 0)
+ {
+ classDef = SAFE_ADDREF(klassDef.p);
+ break;
+ }
+ }
+ }
+ }
+
+ if (NULL == (FdoClassDefinition*)classDef)
+ {
+ //TODO: Refine message if available
+ throw new MgClassNotFoundException(L"MgServerSelectFeatures.IsFunctionOnPrimaryProperty", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ FdoPtr<FdoPropertyDefinitionCollection> properties = classDef->GetProperties();
+ for (FdoInt32 i = 0; i < identifiers->GetCount(); i++)
+ {
+ FdoPtr<FdoIdentifier> identifier = identifiers->GetItem(i);
+ FdoString* name = identifier->GetName();
+ if (properties->IndexOf(name) < 0) //Not in primary class or not recognised
+ {
+#ifdef DEBUG_FDO_JOIN
+ FdoString* funcName = function->GetName();
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) [FDO Join Test] The aggregate function %W contains an unknown or non-primary identifier: %W"), funcName, name));
+#endif
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool MgSelectFeatures::FilterContainsSecondaryProperties(MgResourceIdentifier* featureSourceId, CREFSTRING filter, STRING secondarySchema, STRING secondaryClassName, STRING secondaryPrefix)
+{
+ if (filter.empty())
+ return false;
+
+ //TODO: There's probably a more efficient way to do this without needing to fetch the secondary
+ //class definition. But we're aiming for functionality and simplicity first.
+ Ptr<MgFeatureConnection> conn = new MgFeatureConnection(featureSourceId);
+ {
+ if (!conn->IsConnectionOpen())
+ {
+ throw new MgConnectionFailedException(L"MgServerSelectFeatures.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");
+
+ if (!secondarySchema.empty())
+ {
+ descSchema->SetSchemaName(secondarySchema.c_str());
+ }
+ if (!secondaryClassName.empty())
+ {
+ FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
+ classNames->Add(secondaryClassName.c_str());
+ descSchema->SetClassNames(classNames);
+ }
+
+ FdoPtr<FdoClassDefinition> classDef;
+ FdoPtr<FdoFeatureSchemaCollection> schemas = descSchema->Execute();
+ for (FdoInt32 i = 0; i < schemas->GetCount(); i++)
+ {
+ FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(i);
+ if (wcscmp(schema->GetName(), secondarySchema.c_str()) == 0)
+ {
+ FdoPtr<FdoClassCollection> classes = schema->GetClasses();
+ for (FdoInt32 j = 0; j < classes->GetCount(); j++)
+ {
+ FdoPtr<FdoClassDefinition> klassDef = classes->GetItem(j);
+ if (wcscmp(klassDef->GetName(), secondaryClassName.c_str()) == 0)
+ {
+ classDef = SAFE_ADDREF(klassDef.p);
+ break;
+ }
+ }
+ }
+ }
+
+ if (NULL == (FdoClassDefinition*)classDef)
+ {
+ //TODO: Refine message if available
+ throw new MgClassNotFoundException(L"MgServerSelectFeatures.FilterContainsSecondaryProperties", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ FdoPtr<FdoPropertyDefinitionCollection> propDefs = classDef->GetProperties();
+ for (INT32 i = 0; i < propDefs->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition> propDef = propDefs->GetItem(i);
+ STRING findStr = secondaryPrefix;
+ findStr += propDef->GetName();
+
+ if (filter.find(findStr) != STRING::npos)
+ return true; //The filter string contains this extended feature class property
+ }
+ }
+ return false;
+}
+
+MgReader* MgSelectFeatures::SelectFdoJoin(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName, bool isAggregate)
+{
+ // TODO: This does not handle filters on the secondary side (yet)
+ // Can GwsQueryEngine do this?
+
+ Ptr<MgReader> ret;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ //This could be qualified, so parse it to be sure
+ STRING schemaName;
+ STRING extName;
+ MgUtil::ParseQualifiedClassName(extensionName, schemaName, extName);
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.SelectFdoJoin");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.SelectFdoJoin");
+
+ MdfModel::Extension* extension = NULL;
+ for (INT32 i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* ext = extensions->GetAt(i);
+ if (ext->GetName() == extName)
+ {
+ extension = ext;
+ break;
+ }
+ }
+
+ CHECKNULL(extension, L"MgServerSelectFeatures.SelectFdoJoin");
+ m_command->SetFeatureClassName(extension->GetFeatureClass().c_str());
+ MdfModel::AttributeRelateCollection* relates = extension->GetAttributeRelates();
+ CHECKNULL(relates, L"MgServerSelectFeatures.SelectFdoJoin");
+ MdfModel::AttributeRelate* relate = relates->GetAt(0);
+
+ const MdfModel::MdfString& prefix = relate->GetName();
+
+ STRING primaryAlias = PRIMARY_ALIAS;
+ STRING secondaryAlias = SECONDARY_ALIAS;
+
+ FdoPtr<FdoJoinCriteriaCollection> joinCriteria;
+ if (isAggregate)
+ {
+ MgSelectAggregateCommand* cmd = static_cast<MgSelectAggregateCommand*>(m_command.p);
+ cmd->SetAlias(primaryAlias.c_str());
+ joinCriteria = cmd->GetJoinCriteria();
+ }
+ else
+ {
+ MgSelectCommand* cmd = static_cast<MgSelectCommand*>(m_command.p);
+ cmd->SetAlias(primaryAlias.c_str());
+ joinCriteria = cmd->GetJoinCriteria();
+ }
+
+ Ptr<MgStringCollection> idPropNames = new MgStringCollection();
+ Ptr<MgFeatureConnection> conn = new MgFeatureConnection(featureSourceId);
+ {
+ if (!conn->IsConnectionOpen())
+ {
+ throw new MgConnectionFailedException(L"MgServerSelectFeatures.SelectFdoJoin", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ CHECKNULL(m_command, L"MgServerSelectFeatures.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);
+ ApplyFetchSize();
+
+ //If an explicit list is specified, we assume the caller knows about prefixed
+ //extended feature class properties.
+ Ptr<MgStringCollection> props = m_options->GetClassProperties();
+ if (props->GetCount() > 0)
+ {
+ ApplyClassProperties();
+ bAppliedProperties = true;
+ }
+ }
+
+ //We need to fetch full class definitions of primary and secondary classes
+ if (!bAppliedProperties)
+ {
+ //Add primary class properties
+ STRING primaryClass = extension->GetFeatureClass();
+ STRING primarySchemaName;
+ STRING primaryClassName;
+ MgUtil::ParseQualifiedClassName(primaryClass, primarySchemaName, primaryClassName);
+
+ ApplyClassProperties(fdoConn, primarySchemaName, primaryClassName, idPropNames, primaryAlias);
+
+ if (!isAggregate)
+ {
+ //Add secondary class properties
+ STRING joinClass = relate->GetAttributeClass();
+ STRING joinSchemaName;
+ STRING joinClassName;
+ MgUtil::ParseQualifiedClassName(joinClass, joinSchemaName, joinClassName);
+
+ ApplyClassProperties(fdoConn, joinSchemaName, joinClassName, NULL, secondaryAlias, prefix);
+ }
+ }
+ }
+
+ //Set join type
+ FdoJoinType jtype = FdoJoinType_None;
+ switch(relate->GetRelateType())
+ {
+ case MdfModel::AttributeRelate::Inner:
+ jtype = FdoJoinType_Inner;
+ break;
+ case MdfModel::AttributeRelate::LeftOuter:
+ jtype = FdoJoinType_LeftOuter;
+ break;
+ case MdfModel::AttributeRelate::RightOuter:
+ jtype = FdoJoinType_RightOuter;
+ break;
+ }
+
+ bool bForceOneToOne = relate->GetForceOneToOne();
+ //Set filter for this join
+ STRING secondaryClass = relate->GetAttributeClass();
+ STRING filterText;
+ MdfModel::RelatePropertyCollection* relProps = relate->GetRelateProperties();
+ for (INT32 i = 0; i < relProps->GetCount(); i++)
+ {
+ MdfModel::RelateProperty* prop = relProps->GetAt(i);
+ if (!filterText.empty())
+ {
+ filterText += L" AND ";
+ }
+
+ //[primaryAlias].[PropertyName] = [secondaryAlias].[PropertyName]
+ filterText += primaryAlias;
+ filterText += L".";
+ filterText += prop->GetFeatureClassProperty();
+ filterText += L" = ";
+ filterText += secondaryAlias;
+ filterText += L".";
+ filterText += prop->GetAttributeClassProperty();
+ }
+
+ FdoPtr<FdoJoinCriteria> criteria;
+ FdoPtr<FdoIdentifier> idJoinClass = FdoIdentifier::Create(secondaryClass.c_str());
+ FdoPtr<FdoFilter> filter = FdoFilter::Parse(filterText.c_str());
+ if (prefix.empty())
+ criteria = FdoJoinCriteria::Create(idJoinClass, jtype, filter);
+ else
+ criteria = FdoJoinCriteria::Create(secondaryAlias.c_str(), idJoinClass, jtype, filter);
+
+ joinCriteria->Add(criteria);
+
+ if (isAggregate)
+ ret = ((MgSelectAggregateCommand*)m_command.p)->ExecuteJoined(idPropNames, bForceOneToOne);
+ else
+ ret = ((MgSelectCommand*)m_command.p)->ExecuteJoined(idPropNames, bForceOneToOne);
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerSelectFeatures.SelectFdoJoin")
+
+ return ret.Detach();
+}
+
+void MgSelectFeatures::ApplyAggregateCommandJoinFilterAndCriteria(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName)
+{
+#ifdef DEBUG_FDO_JOIN
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\n\t(%t) Applying FDO join criteria and filter to aggregate command")));
+#endif
+
+ //This could be qualified, so parse it to be sure
+ STRING schemaName;
+ STRING extName;
+ MgUtil::ParseQualifiedClassName(extensionName, schemaName, extName);
+
+ CHECKNULL(m_featureSourceCacheItem.p, L"MgServerSelectFeatures.SupportsFdoJoin");
+ MdfModel::FeatureSource* featureSource = m_featureSourceCacheItem->Get();
+ MdfModel::ExtensionCollection* extensions = featureSource->GetExtensions();
+ CHECKNULL(extensions, L"MgServerSelectFeatures.SupportsFdoJoin");
+
+ MdfModel::Extension* extension = NULL;
+ for (INT32 i = 0; i < extensions->GetCount(); i++)
+ {
+ MdfModel::Extension* ext = extensions->GetAt(i);
+ if (ext->GetName() == extName)
+ {
+ extension = ext;
+ break;
+ }
+ }
+
+ CHECKNULL(extension, L"MgServerSelectFeatures.SelectFdoJoin");
+ m_command->SetFeatureClassName(extension->GetFeatureClass().c_str());
+ MdfModel::AttributeRelateCollection* relates = extension->GetAttributeRelates();
+ CHECKNULL(relates, L"MgServerSelectFeatures.SelectFdoJoin");
+ MdfModel::AttributeRelate* relate = relates->GetAt(0);
+
+ const MdfModel::MdfString& prefix = relate->GetName();
+
+ STRING primaryAlias = PRIMARY_ALIAS;
+ STRING secondaryAlias = SECONDARY_ALIAS;
+
+ MgSelectAggregateCommand* extSelect = static_cast<MgSelectAggregateCommand*>(m_command.p);
+ extSelect->SetAlias(primaryAlias.c_str());
+
+ FdoPtr<FdoJoinCriteriaCollection> joinCriteria = extSelect->GetJoinCriteria();
+
+ //Set join type
+ FdoJoinType jtype = FdoJoinType_None;
+ switch(relate->GetRelateType())
+ {
+ case MdfModel::AttributeRelate::Inner:
+ jtype = FdoJoinType_Inner;
+ break;
+ case MdfModel::AttributeRelate::LeftOuter:
+ jtype = FdoJoinType_LeftOuter;
+ break;
+ case MdfModel::AttributeRelate::RightOuter:
+ jtype = FdoJoinType_RightOuter;
+ break;
+ }
+
+ bool bForceOneToOne = relate->GetForceOneToOne();
+ //Set filter for this join
+ STRING secondaryClass = relate->GetAttributeClass();
+ STRING filterText;
+ MdfModel::RelatePropertyCollection* relProps = relate->GetRelateProperties();
+ for (INT32 i = 0; i < relProps->GetCount(); i++)
+ {
+ MdfModel::RelateProperty* prop = relProps->GetAt(i);
+ if (!filterText.empty())
+ {
+ filterText += L" AND ";
+ }
+
+ //[primaryAlias].[PropertyName] = [secondaryAlias].[PropertyName]
+ filterText += primaryAlias;
+ filterText += L".";
+ filterText += prop->GetFeatureClassProperty();
+ filterText += L" = ";
+ filterText += secondaryAlias;
+ filterText += L".";
+ filterText += prop->GetAttributeClassProperty();
+ }
+
+ FdoPtr<FdoJoinCriteria> criteria;
+ FdoPtr<FdoIdentifier> idJoinClass = FdoIdentifier::Create(secondaryClass.c_str());
+ FdoPtr<FdoFilter> filter = FdoFilter::Parse(filterText.c_str());
+ if (prefix.empty())
+ criteria = FdoJoinCriteria::Create(idJoinClass, jtype, filter);
+ else
+ criteria = FdoJoinCriteria::Create(secondaryAlias.c_str(), idJoinClass, jtype, filter);
+
+ joinCriteria->Add(criteria);
+}
+
+void MgSelectFeatures::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");
+
+ if (!schemaName.empty())
+ {
+ descSchema->SetSchemaName(schemaName.c_str());
+ }
+ if (!className.empty())
+ {
+ FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create();
+ classNames->Add(className.c_str());
+ descSchema->SetClassNames(classNames);
+ }
+
+ FdoPtr<FdoClassDefinition> classDef;
+ FdoPtr<FdoFeatureSchemaCollection> schemas = descSchema->Execute();
+ for (FdoInt32 i = 0; i < schemas->GetCount(); i++)
+ {
+ FdoPtr<FdoFeatureSchema> schema = schemas->GetItem(i);
+ if (wcscmp(schema->GetName(), schemaName.c_str()) == 0)
+ {
+ FdoPtr<FdoClassCollection> classes = schema->GetClasses();
+ for (FdoInt32 j = 0; j < classes->GetCount(); j++)
+ {
+ FdoPtr<FdoClassDefinition> klassDef = classes->GetItem(j);
+ if (wcscmp(klassDef->GetName(), className.c_str()) == 0)
+ {
+ classDef = SAFE_ADDREF(klassDef.p);
+ break;
+ }
+ }
+ }
+ }
+
+ if (NULL == (FdoClassDefinition*)classDef)
+ {
+ //TODO: Refine message if available
+ throw new MgClassNotFoundException(L"MgServerSelectFeatures.ApplyClassProperties", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ FdoPtr<FdoIdentifierCollection> propNames = m_command->GetPropertyNames();
+
+ //Add primary class properties
+ FdoPtr<FdoPropertyDefinitionCollection> propDefs = classDef->GetProperties();
+ for (FdoInt32 i = 0; i < propDefs->GetCount(); i++)
+ {
+ FdoPtr<FdoPropertyDefinition> propDef = propDefs->GetItem(i);
+
+ //Skip ones that aren't data/geometry
+ if (propDef->GetPropertyType() != FdoPropertyType_DataProperty &&
+ propDef->GetPropertyType() != FdoPropertyType_GeometricProperty)
+ continue;
+
+ STRING exprText = alias + L".";
+ exprText += propDef->GetName();
+
+ FdoPtr<FdoExpression> expr = FdoExpression::Parse(exprText.c_str());
+ STRING idName = prefix + propDef->GetName();
+ //[alias].[propertyName] AS [prefix][propertyName]
+ FdoPtr<FdoComputedIdentifier> compId = FdoComputedIdentifier::Create(idName.c_str(), expr);
+
+ propNames->Add(compId);
+ }
+
+ if (NULL != idPropNames)
+ {
+ FdoPtr<FdoDataPropertyDefinitionCollection> idPropDefs = classDef->GetIdentityProperties();
+ for (FdoInt32 i = 0; i < idPropDefs->GetCount(); i++)
+ {
+ FdoPtr<FdoDataPropertyDefinition> dp = idPropDefs->GetItem(i);
+ STRING propName = L"";
+ propName += dp->GetName();
+ idPropNames->Add(propName);
+ }
+ }
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SelectFeatures.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,104 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef DESKTOP_SELECT_FEATURES_H_
+#define DESKTOP_SELECT_FEATURES_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+#include "Services/Feature/GwsFeatureReader.h"
+
+class MgFeatureQueryOptions;
+class MgFeatureServiceCommand;
+template class Ptr<MgFeatureSourceCacheItem>;
+
+class MgSelectFeatures
+{
+public:
+ MgSelectFeatures();
+ ~MgSelectFeatures();
+ MgReader* SelectFeatures(MgResourceIdentifier* resource,
+ CREFSTRING className,
+ MgFeatureQueryOptions* options,
+ bool isSelectAggregate);
+
+private:
+ void ApplyQueryOptions(bool isSelectAggregate);
+ void ApplyClassProperties();
+ void ApplyComputedProperties();
+ void ApplyFilter();
+ // void ApplySpatialFilter();
+ void ApplyOrderingOptions();
+ void ApplyFetchSize();
+
+ //bool HasCustomProperty() { return m_customPropertyFound; }
+ //FdoFunction* GetCustomFunction() { return FDO_SAFE_ADDREF(m_customFunction); }
+ //STRING GetCustomPropertyName() { return m_customPropertyName; }
+
+ bool IsFdoSupportedFunction(FdoIConnection* connection, FdoFunction* fdoFunc);
+ bool ContainsUdf(FdoExpression* expression);
+ bool IsCustomFunction(FdoFunction* fdoFunc);
+ void AddFdoComputedProperty(CREFSTRING aliasName, FdoExpression* expression);
+ void AddCustomComputedProperty(CREFSTRING aliasName, FdoExpression* expression);
+ void ValidateConstraintsOnCustomFunctions();
+ void ApplyAggregateOptions(bool isSelectAggregate);
+ void CreateCommand(MgResourceIdentifier* resource, bool isSelectAggregate);
+ void ValidateParam(MgResourceIdentifier* resource, CREFSTRING className);
+ void ApplyFdoGroupingProperties(MgStringCollection* propertyNames);
+ bool ContainsCustomFunction(MgFeatureQueryOptions* options);
+ MgReader* GetCustomReader(MgReader* reader);
+
+ // STRING m_providerName;
+ STRING className;
+ Ptr<MgStringCollection> properties;
+ Ptr<MgFeatureQueryOptions> m_options;
+ STRING filterText;
+ Ptr<MgFeatureServiceCommand> m_command;
+
+ Ptr<MgFeatureSourceCacheItem> m_featureSourceCacheItem;
+
+ // Only one custom property is supported. No nesting of custom properties allowed.
+ STRING m_customPropertyName;
+ bool m_customPropertyFound;
+ FdoPtr<FdoFunction> m_customFunction;
+
+ // Methods for Feature Join
+ bool FindFeatureJoinProperties(MgResourceIdentifier* resourceId, CREFSTRING extensionName);
+ bool FindFeatureCalculation(MgResourceIdentifier* resourceId, CREFSTRING extensionName);
+ MgdGwsFeatureReader* JoinFeatures(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName, FdoFilter* filter);
+ void UpdateCommandOnCalculation(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName);
+ void UpdateCommandOnJoinCalculation(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName);
+ void ParseQualifiedClassNameForCalculation(MdfModel::Extension* extension, CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className);
+ MgResourceIdentifier* GetSecondaryResourceIdentifier(MgResourceIdentifier* primResId, CREFSTRING extensionName, CREFSTRING relationName);
+
+ // This setting limits the batch size used by the join query algorithm
+ INT32 m_nJoinQueryBatchSize;
+
+ INT32 m_nDataCacheSize;
+
+ // FDO join optimization
+ 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);
+ void ApplyAggregateCommandJoinFilterAndCriteria(MgResourceIdentifier* featureSourceId, CREFSTRING extension);
+ void ApplyClassProperties(FdoIConnection* fdoConn, CREFSTRING schemaName, CREFSTRING className, MgStringCollection* idPropNames, CREFSTRING alias, CREFSTRING prefix = L"");
+ bool FilterContainsSecondaryProperties(MgResourceIdentifier* featureSourceId, CREFSTRING filter, STRING secondarySchema, STRING secondaryClassName, STRING secondaryPrefix);
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,188 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "Services/FeatureService.h"
+#include "SqlCommand.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "Services/SqlDataReader.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "Services/Transaction.h"
+
+MgServerSqlCommand::MgServerSqlCommand()
+{
+}
+
+MgServerSqlCommand::~MgServerSqlCommand()
+{
+ MG_TRY()
+
+ CloseConnection();
+
+ MG_CATCH_AND_RELEASE()
+}
+
+void MgServerSqlCommand::CloseConnection()
+{
+ // The FDO connection must be released before the parent object is released
+ m_fdoConn = NULL;
+ m_featureConnection = NULL;
+}
+
+// Executes the describe schema command and serializes the schema to XML
+MgSqlDataReader* MgServerSqlCommand::ExecuteQuery(
+ MgResourceIdentifier* resource,
+ CREFSTRING sqlStatement,
+ MgParameterCollection* params,
+ MgTransaction* transaction,
+ INT32 fetchSize)
+{
+ Ptr<MgSqlDataReader> mgSqlDataReader;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ // If validation does succeeds, it will throw exception
+ Validate(resource, sqlStatement, FdoCommandType_SQLCommand, transaction);
+
+ // Create the SQL command
+ FdoPtr<FdoISQLCommand> fdoCommand = (FdoISQLCommand*)m_fdoConn->CreateCommand(FdoCommandType_SQLCommand);
+ CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgServerSqlCommand.ExecuteQuery");
+
+ // Set SQL statement
+ fdoCommand->SetSQLStatement((FdoString*)sqlStatement.c_str());
+
+ // Set fetch size
+ fdoCommand->SetFetchSize(fetchSize);
+
+ // Set parameters
+ FdoPtr<FdoParameterValueCollection> fdoParams = NULL;
+ if (NULL != params && params->GetCount() > 0)
+ {
+ fdoParams = fdoCommand->GetParameterValues();
+ MgFeatureUtil::FillFdoParameterCollection(params, fdoParams);
+ }
+
+ // Execute the command
+ FdoPtr<FdoISQLDataReader> sqlReader = fdoCommand->ExecuteReader();
+ CHECKNULL((FdoISQLDataReader*)sqlReader, L"MgServerSqlCommand.ExecuteQuery");
+
+ // Update parameter whose direction is InputOutput, Output, or Return.
+ if (NULL != params && params->GetCount() > 0)
+ MgFeatureUtil::UpdateParameterCollection(fdoParams, params);
+
+ mgSqlDataReader = new MgdSqlDataReader(m_featureConnection, sqlReader); //, m_providerName);
+ CHECKNULL((MgSqlDataReader*)mgSqlDataReader, L"MgServerSqlCommand.ExecuteQuery");
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerSqlCommand.ExecuteQuery")
+
+ return mgSqlDataReader.Detach();
+}
+
+// Executes the describe schema command and serializes the schema to XML
+INT32 MgServerSqlCommand::ExecuteNonQuery(
+ MgResourceIdentifier* resource,
+ CREFSTRING sqlStatement,
+ MgParameterCollection* params,
+ MgTransaction* transaction)
+{
+ INT32 rowsAffected = 0;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ // If validation does succeeds, it will throw exception
+ Validate(resource, sqlStatement, FdoCommandType_SQLCommand, transaction);
+
+ // Create the SQL command
+ FdoPtr<FdoISQLCommand> fdoCommand = (FdoISQLCommand*)m_fdoConn->CreateCommand(FdoCommandType_SQLCommand);
+ CHECKNULL((FdoISQLCommand*)fdoCommand, L"MgServerSqlCommand.ExecuteQuery");
+
+ // Set SQL statement
+ fdoCommand->SetSQLStatement((FdoString*)sqlStatement.c_str());
+
+ // Set parameters
+ FdoPtr<FdoParameterValueCollection> fdoParams = NULL;
+ if (NULL != params && params->GetCount() > 0)
+ {
+ fdoParams = fdoCommand->GetParameterValues();
+ MgFeatureUtil::FillFdoParameterCollection(params, fdoParams);
+ }
+
+ // Execute the command
+ rowsAffected = fdoCommand->ExecuteNonQuery();
+
+ // Update parameter whose direction is InputOutput, Output, or Return.
+ if (NULL != params && params->GetCount() > 0)
+ MgFeatureUtil::UpdateParameterCollection(fdoParams, params);
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerSqlCommand.ExecuteQuery")
+
+ return rowsAffected;
+}
+
+
+void MgServerSqlCommand::Validate(MgResourceIdentifier* resource, CREFSTRING sqlStatement, INT32 commandType, MgTransaction* transaction)
+{
+ // SQL statement can not be empty
+ if (resource == NULL)
+ {
+ throw new MgNullArgumentException(L"MgServerSqlCommand.Validate", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ if (sqlStatement.empty())
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"2");
+ arguments.Add(MgResources::BlankArgument);
+
+ throw new MgInvalidArgumentException(L"MgServerSqlCommand.Validate",
+ __LINE__, __WFILE__, &arguments, L"MgStringEmpty", NULL);
+ }
+
+ // Close any previously opened connection.
+ CloseConnection();
+
+ // Connect to provider
+ if (NULL != transaction)
+ {
+ // grab the connection used to start the transaction.
+ MgdTransaction* featureTransaction = static_cast<MgdTransaction*>(transaction);
+ m_featureConnection = featureTransaction->GetConnection();
+ }
+ else
+ {
+ // No transaction, grab the connection as usual.
+ m_featureConnection = new MgFeatureConnection(resource);
+ }
+
+ if (m_featureConnection->IsConnectionOpen() )
+ {
+ m_fdoConn = m_featureConnection->GetConnection();
+ m_providerName = m_featureConnection->GetProviderName();
+
+ // Check whether command is supported by provider
+ if (!m_featureConnection->SupportsCommand(commandType))
+ {
+ // TODO: specify which argument and message, once we have the mechanism
+ STRING message = MgFeatureUtil::GetMessage(L"MgCommandNotSupported");
+ throw new MgInvalidOperationException(L"MgServerSqlCommand.Validate", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ }
+ else
+ {
+ throw new MgConnectionFailedException(L"MgServerSqlCommand::Validate", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/SqlCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_SQLCOMMAND_H_
+#define _MG_SERVER_SQLCOMMAND_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgFeatureConnection;
+
+class MgServerSqlCommand
+{
+public:
+ MgServerSqlCommand();
+ ~MgServerSqlCommand();
+ MgSqlDataReader* ExecuteQuery(
+ MgResourceIdentifier* resource,
+ CREFSTRING sqlStatement,
+ MgParameterCollection* params,
+ MgTransaction* transaction,
+ INT32 fetchSize = 0);
+ INT32 ExecuteNonQuery(
+ MgResourceIdentifier* resource,
+ CREFSTRING sqlStatement,
+ MgParameterCollection* params,
+ MgTransaction* transaction);
+
+private:
+ void Validate(MgResourceIdentifier* resource, CREFSTRING sqlStatement, INT32 commandType, MgTransaction* transaction);
+ void CloseConnection();
+
+private:
+ STRING m_providerName;
+ STRING m_sqlStatement;
+ FdoPtr<FdoIConnection> m_fdoConn;
+ Ptr<MgFeatureConnection> m_featureConnection;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,73 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "MgDesktop.h"
+#include "Services/FeatureService.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "FeatureManipulationCommand.h"
+#include "UpdateCommand.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "Services/FeatureReader.h"
+
+MgServerUpdateCommand::MgServerUpdateCommand()
+{
+ m_srvrFeatConn = NULL;
+ m_featCommand = NULL;
+}
+
+MgServerUpdateCommand::MgServerUpdateCommand(MgFeatureCommand* command, MgFeatureConnection* connection, INT32 cmdId)
+{
+ CHECKNULL(command, L"MgServerUpdateCommand.MgServerUpdateCommand");
+ CHECKNULL(connection, L"MgServerUpdateCommand.MgServerUpdateCommand");
+
+ m_srvrFeatConn = SAFE_ADDREF((MgFeatureConnection*)connection);
+ m_featCommand = SAFE_ADDREF((MgUpdateFeatures*)command);
+ m_cmdId = cmdId;
+}
+
+MgServerUpdateCommand::~MgServerUpdateCommand()
+{
+ m_srvrFeatConn = NULL;
+}
+
+MgProperty* MgServerUpdateCommand::Execute()
+{
+ STRING clsName = m_featCommand->GetFeatureClassName();
+ STRING filterText = m_featCommand->GetFilterText();
+ Ptr<MgPropertyCollection> propCol = m_featCommand->GetPropertyValues();
+
+ FdoPtr<FdoIConnection> fdoConn = m_srvrFeatConn->GetConnection();
+
+ // Create the SQL command
+ FdoPtr<FdoIUpdate> fdoCommand = (FdoIUpdate*)fdoConn->CreateCommand(FdoCommandType_Update);
+ CHECKNULL((FdoIUpdate*)fdoCommand, L"MgServerUpdateCommand.Execute");
+
+ fdoCommand->SetFeatureClassName(clsName.c_str());
+ fdoCommand->SetFilter(filterText.c_str());
+
+ FdoPtr<FdoPropertyValueCollection> paramValCol = fdoCommand->GetPropertyValues();
+ MgFeatureUtil::FillFdoPropertyCollection(propCol, paramValCol);
+
+ INT32 recordsUpdated = fdoCommand->Execute();
+
+ char buff[32];
+ sprintf(buff, "%d", m_cmdId);
+ STRING str = MgUtil::MultiByteToWideChar(string(buff));
+
+ return new MgInt32Property(str, recordsUpdated);
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateCommand.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_UPDATE_COMMAND_H_
+#define _MG_SERVER_UPDATE_COMMAND_H_
+
+class MgFeatureConnection;
+
+class MgServerUpdateCommand : public MgFeatureManipulationCommand
+{
+ DECLARE_CLASSNAME(MgServerUpdateCommand)
+
+public:
+ MgServerUpdateCommand(MgFeatureCommand* command, MgFeatureConnection* connection, INT32 cmdId);
+ virtual MgProperty* Execute();
+protected:
+ MgServerUpdateCommand();
+ ~MgServerUpdateCommand();
+private:
+ Ptr<MgUpdateFeatures> m_featCommand;
+ Ptr<MgFeatureConnection> m_srvrFeatConn;
+ INT32 m_cmdId;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,221 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "Services/Feature/FeatureDefs.h"
+#include "Services/FeatureService.h"
+#include "Services/Feature/FeatureConnection.h"
+#include "UpdateFeatures.h"
+#include "Services/Feature/FeatureUtil.h"
+#include "FeatureManipulationCommand.h"
+#include "Services/Feature/FeatureServiceCache.h"
+#include "Services/Transaction.h"
+
+MgServerUpdateFeatures::MgServerUpdateFeatures()
+{
+ m_SrvrFeatConn = NULL;
+}
+
+MgServerUpdateFeatures::~MgServerUpdateFeatures()
+{
+}
+
+void MgServerUpdateFeatures::Connect(MgResourceIdentifier* resource, MgTransaction* transaction)
+{
+ if (NULL == transaction)
+ {
+ m_SrvrFeatConn = new MgFeatureConnection(resource);
+ }
+ else
+ {
+ MgdTransaction* featTransaction = static_cast<MgdTransaction*>(transaction);
+ m_SrvrFeatConn = featTransaction->GetConnection();
+ }
+
+ if ((NULL != m_SrvrFeatConn.p) && ( !m_SrvrFeatConn->IsConnectionOpen() ))
+ {
+
+ throw new MgConnectionFailedException(L"MgServerUpdateFeatures::MgServerUpdateFeatures()",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+}
+
+// Executes the commands
+MgPropertyCollection* MgServerUpdateFeatures::Execute(MgResourceIdentifier* resource,
+ MgFeatureCommandCollection* commands,
+ bool useTransaction)
+{
+ Ptr<MgPropertyCollection> propCol;
+ FdoITransaction* transaction = NULL;
+ bool commited = false;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ if (resource == NULL || commands == NULL)
+ {
+ throw new MgNullArgumentException(L"MgServerUpdateFeatures.UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ INT32 cnt = commands->GetCount();
+ if (cnt == 0)
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"2");
+ arguments.Add(L"0");
+
+ throw new MgInvalidArgumentException(L"MgServerUpdateFeatures.UpdateFeatures",
+ __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
+ }
+
+ // Connect to provider
+ Connect(resource, NULL);
+
+ propCol = new MgPropertyCollection();
+
+ FdoPtr<FdoIConnection> fdoConn = m_SrvrFeatConn->GetConnection();
+ if (useTransaction)
+ {
+ transaction = fdoConn->BeginTransaction();
+ }
+
+ for (INT32 i = 0; i < cnt; i++)
+ {
+ Ptr<MgProperty> result;
+ Ptr<MgFeatureCommand> command = commands->GetItem(i);
+ Ptr<MgFeatureManipulationCommand> fmServerCommand = MgFeatureManipulationCommand::CreateCommand(command, m_SrvrFeatConn, i);
+
+ MG_FEATURE_SERVICE_TRY()
+ // Execute the manipulation command
+ result = fmServerCommand->Execute();
+
+ MG_FEATURE_SERVICE_CATCH(L"MgServerUpdateFeatures.UpdateFeatures")
+
+ if (transaction != NULL)
+ {
+ MG_FEATURE_SERVICE_THROW() // rethrow if updates are done in transaction
+ }
+ else
+ {
+ if (mgException != NULL)
+ {
+ // When an exception is thrown, we need to communicate this back to user in non-transactional case.
+ // We can do this either by setting warnings or a string property. Making it as StringProperty would
+ // let users know exactly which ones failed and why.
+ STRING str;
+ MgUtil::Int32ToString(i, str);
+ STRING errMsg = mgException->GetDetails();
+
+ result = new MgStringProperty(str, errMsg); // If there is an exception which means result would null from execute
+ mgException = NULL; // Release the pointer
+ }
+ }
+ // NULL property should not be added.
+ if (result != NULL)
+ {
+ propCol->Add(result);
+ }
+ }
+
+ if (transaction != NULL)
+ {
+ transaction->Commit();
+ commited = true;
+ }
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerUpdateFeatures.UpdateFeatures")
+
+ if (transaction != NULL && !commited)
+ {
+ transaction->Rollback();
+ }
+
+ MG_FEATURE_SERVICE_THROW()
+
+ return propCol.Detach();
+}
+
+// Executes the commands
+MgPropertyCollection* MgServerUpdateFeatures::Execute(MgResourceIdentifier* resource,
+ MgFeatureCommandCollection* commands,
+ MgTransaction* transaction)
+{
+ Ptr<MgPropertyCollection> propCol;
+
+ MG_FEATURE_SERVICE_TRY()
+
+ if (resource == NULL || commands == NULL)
+ {
+ throw new MgNullArgumentException(L"MgServerUpdateFeatures.UpdateFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ INT32 cnt = commands->GetCount();
+ if (cnt == 0)
+ {
+ MgStringCollection arguments;
+ arguments.Add(L"2");
+ arguments.Add(L"0");
+
+ throw new MgInvalidArgumentException(L"MgServerUpdateFeatures.UpdateFeatures",
+ __LINE__, __WFILE__, &arguments, L"MgCollectionEmpty", NULL);
+ }
+
+ // Connect to provider
+ Connect(resource, transaction);
+
+ propCol = new MgPropertyCollection();
+
+ for (INT32 i = 0; i < cnt; i++)
+ {
+ Ptr<MgProperty> result;
+ Ptr<MgFeatureCommand> command = commands->GetItem(i);
+ Ptr<MgFeatureManipulationCommand> fmServerCommand = MgFeatureManipulationCommand::CreateCommand(command, m_SrvrFeatConn, i);
+
+ MG_FEATURE_SERVICE_TRY()
+ // Execute the manipulation command
+ result = fmServerCommand->Execute();
+
+ MG_FEATURE_SERVICE_CATCH(L"MgServerUpdateFeatures.UpdateFeatures")
+
+ if (transaction != NULL)
+ {
+ MG_FEATURE_SERVICE_THROW() // rethrow if updates are done in transaction
+ }
+ else
+ {
+ if (mgException != NULL)
+ {
+ // When an exception is thrown, we need to communicate this back to user in non-transactional case.
+ // We can do this either by setting warnings or a string property. Making it as StringProperty would
+ // let users know exactly which ones failed and why.
+ STRING str;
+ MgUtil::Int32ToString(i, str);
+ STRING errMsg = mgException->GetDetails();
+
+ result = new MgStringProperty(str, errMsg); // If there is an exception which means result would null from execute
+ mgException = NULL; // Release the pointer
+ }
+ }
+ // NULL property should not be added.
+ if (result != NULL)
+ {
+ propCol->Add(result);
+ }
+ }
+
+ MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgServerUpdateFeatures.UpdateFeatures")
+
+ return propCol.Detach();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Commands/UpdateFeatures.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,52 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MG_SERVER_UPDATE_FEATURES_H_
+#define _MG_SERVER_UPDATE_FEATURES_H_
+
+#include "MgDesktop.h"
+#include "System/XmlDefs.h"
+#include "System/XmlUtil.h"
+#include "Fdo.h"
+
+class MgFeatureConnection;
+class MgFeatureCommandCollection;
+class MgIntCollection;
+
+class MgServerUpdateFeatures
+{
+public:
+ MgServerUpdateFeatures();
+ ~MgServerUpdateFeatures();
+ MgPropertyCollection* Execute(MgResourceIdentifier* resource,
+ MgFeatureCommandCollection* commands,
+ bool useTransaction);
+
+ MgPropertyCollection* Execute(MgResourceIdentifier* resource,
+ MgFeatureCommandCollection* commands,
+ MgTransaction* transaction);
+
+private:
+ void Connect(MgResourceIdentifier* resource, MgTransaction* transaction);
+
+private:
+
+ Ptr<MgFeatureConnection> m_SrvrFeatConn;
+ STRING m_providerName;
+};
+
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,470 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "stdafx.h"
+#include <assert.h>
+#include "Fdo.h"
+#include "FdoCommon.h"
+#include "FdoFeatureReader.h"
+
+#include <limits> // For quiet_NaN()
+using namespace std;
+
+
+// Class MgFdoFeatureReader
+MgFdoFeatureReader::MgFdoFeatureReader() : m_currentReaderId(-1)
+{
+ m_readerDepleted = false;
+ m_readerCollection = MgFdoReaderCollection::Create();
+}
+
+MgFdoFeatureReader::MgFdoFeatureReader(MgFdoReaderCollection *readerCollection) : m_currentReaderId(-1)
+{
+ m_readerDepleted = false;
+ m_readerCollection = FDO_SAFE_ADDREF(readerCollection);
+}
+
+MgFdoFeatureReader::~MgFdoFeatureReader()
+{
+ MG_TRY()
+
+ Close();
+
+ MG_CATCH_AND_RELEASE()
+}
+
+void MgFdoFeatureReader::Dispose()
+{
+ delete this;
+}
+
+FdoClassDefinition *MgFdoFeatureReader::GetClassDefinition()
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetClassDefinition();
+}
+
+
+int MgFdoFeatureReader::GetDepth()
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetDepth();
+}
+
+FdoString* MgFdoFeatureReader::GetPropertyName(FdoInt32 index)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetPropertyName(index);
+}
+
+FdoInt32 MgFdoFeatureReader::GetPropertyIndex(FdoString* propertyName)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetPropertyIndex(propertyName);
+}
+
+FdoIFeatureReader* MgFdoFeatureReader::GetFeatureObject( const wchar_t* propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetFeatureObject(propertyName);
+}
+
+FdoIFeatureReader* MgFdoFeatureReader::GetFeatureObject( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetFeatureObject(index);
+}
+
+bool MgFdoFeatureReader::GetBoolean( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetBoolean(propertyName);
+}
+
+bool MgFdoFeatureReader::GetBoolean( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetBoolean(index);
+}
+
+FdoByte MgFdoFeatureReader::GetByte( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetByte(propertyName);
+}
+
+FdoByte MgFdoFeatureReader::GetByte( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetByte(index);
+}
+
+FdoDateTime MgFdoFeatureReader::GetDateTime( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetDateTime(propertyName);
+}
+
+FdoDateTime MgFdoFeatureReader::GetDateTime( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetDateTime(index);
+}
+
+double MgFdoFeatureReader::GetDouble( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetDouble(propertyName);
+}
+
+double MgFdoFeatureReader::GetDouble( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetDouble(index);
+}
+
+const wchar_t* MgFdoFeatureReader::GetString( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetString(propertyName);
+
+}
+
+const wchar_t* MgFdoFeatureReader::GetString( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetString(index);
+
+}
+
+short MgFdoFeatureReader::GetInt16( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetInt16(propertyName);
+}
+
+short MgFdoFeatureReader::GetInt16( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetInt16(index);
+}
+
+int MgFdoFeatureReader::GetInt32( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetInt32(propertyName);
+}
+
+int MgFdoFeatureReader::GetInt32( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetInt32(index);
+}
+
+FdoInt64 MgFdoFeatureReader::GetInt64( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetInt64(propertyName);
+}
+
+FdoInt64 MgFdoFeatureReader::GetInt64( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetInt64(index);
+}
+
+float MgFdoFeatureReader::GetSingle( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetSingle(propertyName);
+}
+
+float MgFdoFeatureReader::GetSingle( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetSingle(index);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+FdoIStreamReader* MgFdoFeatureReader::GetLOBStreamReader(const wchar_t* propertyName)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetLOBStreamReader(propertyName);
+}
+
+FdoIStreamReader* MgFdoFeatureReader::GetLOBStreamReader(FdoInt32 index)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetLOBStreamReader(index);
+}
+///////////////////////////////////////////////////////////////////////////////
+FdoLOBValue* MgFdoFeatureReader::GetLOB(const wchar_t* propertyName)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetLOB(propertyName);
+}
+
+FdoLOBValue* MgFdoFeatureReader::GetLOB(FdoInt32 index)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetLOB(index);
+}
+
+bool MgFdoFeatureReader::IsNull( const wchar_t *propertyName )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->IsNull(propertyName);
+}
+
+bool MgFdoFeatureReader::IsNull( FdoInt32 index )
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->IsNull(index);
+}
+
+FdoByteArray* MgFdoFeatureReader::GetGeometry(const wchar_t* propertyName)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetGeometry(propertyName);
+}
+
+FdoByteArray* MgFdoFeatureReader::GetGeometry(FdoInt32 index)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetGeometry(index);
+}
+
+const FdoByte * MgFdoFeatureReader::GetGeometry(const wchar_t* propertyName, FdoInt32 * count)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetGeometry(propertyName, count);
+}
+
+const FdoByte * MgFdoFeatureReader::GetGeometry(FdoInt32 index, FdoInt32 * count)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetGeometry(index, count);
+}
+
+/// <summary>Gets the raster object of the specified property.
+/// Because no conversion is performed, the property must be
+/// of Raster type; otherwise, an exception is thrown.</summary>
+/// <param name="propertyName">Input the property name.</param>
+/// <returns>Returns the raster object.</returns>
+FdoIRaster* MgFdoFeatureReader::GetRaster(FdoString* propertyName)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetRaster(propertyName);
+}
+
+FdoIRaster* MgFdoFeatureReader::GetRaster(FdoInt32 index)
+{
+ if (m_currentReader == NULL)
+ {
+ Initialize();
+ }
+
+ return m_currentReader->GetRaster(index);
+}
+
+bool MgFdoFeatureReader::ReadNext( )
+{
+ if (m_readerDepleted)
+ return false;
+
+ if (m_currentReader == NULL)
+ Initialize();
+
+ if (m_currentReader->ReadNext())
+ return true;
+
+ m_currentReader = NULL;
+ m_currentReaderId++;
+ if ((m_readerCollection->GetCount() > m_currentReaderId))
+ m_currentReader = static_cast<FdoIFeatureReader*>(m_readerCollection->GetItem(m_currentReaderId));
+
+ if (m_currentReader != NULL)
+ return this->ReadNext();
+
+ m_readerDepleted = true;
+ return false;
+}
+
+void MgFdoFeatureReader::Close( )
+{
+ if (m_currentReader)
+ {
+ m_currentReader->Close();
+ }
+}
+
+void MgFdoFeatureReader::Add(FdoIFeatureReader *reader)
+{
+ m_readerCollection->Add(reader);
+}
+
+void MgFdoFeatureReader::Initialize()
+{
+ if (m_currentReader == NULL)
+ {
+ if (m_readerCollection->GetCount())
+ {
+ m_currentReader = (FdoIFeatureReader*)m_readerCollection->GetItem(0);
+ m_currentReaderId = 0;
+ }
+ }
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFeatureReader.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,100 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MGFDOFEATUREREADER_H
+#define _MGFDOFEATUREREADER_H
+
+#include "FdoReaderCollection.h"
+
+class FdoIFeatureReader;
+
+class MgFdoFeatureReader: public FdoIFeatureReader
+{
+public:
+ // constructs a MgFdoFeatureReader
+ MgFdoFeatureReader();
+ MgFdoFeatureReader(MgFdoReaderCollection* readerCollection);
+ // default destructor
+ virtual ~MgFdoFeatureReader();
+
+protected:
+
+ virtual void Dispose();
+
+public:
+
+ virtual FdoClassDefinition* GetClassDefinition();
+ virtual int GetDepth();
+ virtual bool GetBoolean( const wchar_t *propertyName );
+ virtual FdoByte GetByte( const wchar_t *propertyName );
+ virtual double GetDouble(const wchar_t* propertyName);
+ virtual short GetInt16( const wchar_t *propertyName );
+ virtual int GetInt32( const wchar_t *propertyName );
+ virtual FdoInt64 GetInt64( const wchar_t *propertyName );
+ virtual float GetSingle( const wchar_t *propertyName );
+ virtual const wchar_t* GetString( const wchar_t *propertyName );
+
+ virtual FdoLOBValue* GetLOB(const wchar_t* propertyName );
+ virtual FdoIStreamReader* GetLOBStreamReader(const wchar_t* propertyName );
+
+ virtual bool IsNull( const wchar_t *propertyName );
+ virtual FdoIFeatureReader* GetFeatureObject(const wchar_t* propertyName);
+ virtual FdoByteArray* GetGeometry(const wchar_t* propertyName);
+ virtual const FdoByte * GetGeometry(const wchar_t* propertyName, FdoInt32 * count);
+ virtual FdoIRaster* GetRaster(const wchar_t* propertyName);
+
+ virtual bool IsNull (FdoInt32 index);
+ virtual const wchar_t* GetString (FdoInt32 index);
+ virtual bool GetBoolean (FdoInt32 index);
+ virtual FdoByte GetByte (FdoInt32 index);
+ virtual FdoDateTime GetDateTime (FdoInt32 index);
+ virtual double GetDouble (FdoInt32 index);
+ virtual short GetInt16 (FdoInt32 index);
+ virtual int GetInt32 (FdoInt32 index);
+ virtual FdoInt64 GetInt64 (FdoInt32 index);
+ virtual float GetSingle (FdoInt32 index);
+ virtual FdoLOBValue* GetLOB (FdoInt32 index);
+ virtual FdoIStreamReader* GetLOBStreamReader (FdoInt32 index);
+ virtual FdoIRaster* GetRaster (FdoInt32 index);
+ virtual const FdoByte * GetGeometry (FdoInt32 index, FdoInt32 * count);
+ virtual FdoByteArray* GetGeometry (FdoInt32 index);
+ virtual FdoIFeatureReader* GetFeatureObject (FdoInt32 index);
+
+ virtual FdoString* GetPropertyName(FdoInt32 index);
+ virtual FdoInt32 GetPropertyIndex(FdoString* propertyName);
+
+ virtual bool ReadNext( );
+ virtual void Close();
+
+
+ virtual FdoDateTime GetDateTime(const wchar_t *propertyName );
+
+ // Add an FdoIFeatureReader to the reader collection
+ void Add(FdoIFeatureReader* reader);
+
+protected:
+
+private:
+ FdoPtr<MgFdoReaderCollection> m_readerCollection;
+ FdoPtr<FdoIFeatureReader> m_currentReader;
+ FdoInt32 m_currentReaderId;
+ FdoBoolean m_readerDepleted;
+ void Initialize();
+
+};
+
+#endif // _MGFDOFEATUREREADER_H
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,24 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "stdafx.h"
+#include "FdoFilterCollection.h"
+
+/*FDO_API*/ MgFdoFilterCollection* MgFdoFilterCollection::Create()
+{
+ return new MgFdoFilterCollection();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoFilterCollection.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MGFDOFILTERCOLLECTION_H_
+#define _MGFDOFILTERCOLLECTION_H_
+
+#include <FdoStd.h>
+
+class FdoFilter;
+
+/// \brief
+/// The MgFdoFilterCollection class represents a collection of FdoFilter objects.
+class MgFdoFilterCollection : public FdoCollection<FdoFilter, FdoException>
+{
+protected:
+/// \cond DOXYGEN-IGNORE
+ MgFdoFilterCollection() : FdoCollection<FdoFilter, FdoException>()
+ {
+ }
+
+ virtual ~MgFdoFilterCollection()
+ {
+ }
+
+ virtual void Dispose()
+ {
+ delete this;
+ }
+/// \endcond
+
+public:
+ /// \brief
+ /// Constructs a default instance of an MgFdoFilterCollection.
+ ///
+ /// \return
+ /// Returns MgFdoFilterCollection
+ ///
+ /*FDO_API*/ static MgFdoFilterCollection* Create();
+};
+#endif
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,24 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#include "stdafx.h"
+#include "FdoReaderCollection.h"
+
+/*FDO_API*/ MgFdoReaderCollection* MgFdoReaderCollection::Create()
+{
+ return new MgFdoReaderCollection();
+}
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FdoReaderCollection.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#ifndef _MGFDOREADERCOLLECTION_H_
+#define _MGFDOREADERCOLLECTION_H_
+
+#include <FdoStd.h>
+
+class FdoIFeatureReader;
+
+/// \brief
+/// The MgFdoReaderCollection class represents a collection of FdoIFeatureReader objects.
+class MgFdoReaderCollection : public FdoCollection<FdoIFeatureReader, FdoException>
+{
+protected:
+/// \cond DOXYGEN-IGNORE
+ MgFdoReaderCollection() : FdoCollection<FdoIFeatureReader, FdoException>()
+ {
+ }
+
+ virtual ~MgFdoReaderCollection()
+ {
+ }
+
+ virtual void Dispose()
+ {
+ delete this;
+ }
+/// \endcond
+
+public:
+ /// \brief
+ /// Constructs a default instance of an MgFdoReaderCollection.
+ ///
+ /// \return
+ /// Returns MgFdoReaderCollection
+ ///
+ /*FDO_API*/ static MgFdoReaderCollection* Create();
+};
+#endif
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDefs.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDefs.h 2012-07-15 15:04:11 UTC (rev 6902)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDefs.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -155,4 +155,7 @@
MG_FEATURE_SERVICE_THROW() \
-#endif
\ No newline at end of file
+#endif
+
+#define PRIMARY_ALIAS L"a"
+#define SECONDARY_ALIAS L"b"
\ No newline at end of file
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.cpp (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,841 @@
+#include "MgDesktop.h"
+#include "FeatureSetReader.h"
+
+#define CHECK_FEATURESET_COUNT(pointer, methodname) \
+if (0 == pointer->GetCount()) \
+{ \
+ throw new MgEmptyFeatureSetException(methodname, \
+ __LINE__, __WFILE__, NULL, L"", NULL); \
+}
+
+#define CHECK_PROPERTY_TYPE(property, type, methodname) \
+if (property != type) \
+{ \
+ throw new MgInvalidPropertyTypeException(methodname, \
+ __LINE__, __WFILE__, NULL, L"", NULL); \
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Construct a MgdFeatureSetReader object from a byte source
+///</summary>
+///<param name="byteSource">Byte source object</param>
+///
+MgdFeatureSetReader::MgdFeatureSetReader(MgFeatureSet* featureSet)
+{
+ m_currRecord = 0;
+ m_set = SAFE_ADDREF(featureSet);
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Destruct a MgdFeatureSetReader object
+///</summary>
+///
+MgdFeatureSetReader::~MgdFeatureSetReader()
+{
+ Close();
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Set the byte source for an empty reader
+///</summary>
+///<param name="byteSource">Byte source object</param>
+///
+void MgdFeatureSetReader::AssignFeatureSet(MgFeatureSet* featureSet)
+{
+ m_currRecord = 0;
+ m_set = SAFE_ADDREF(featureSet);
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Advances the reader to the next item and returns true if there is
+/// another object to read or false if reading is complete. The default
+/// position of the reader is prior to the first item. Thus you must
+/// call ReadNext to begin accessing any data.
+/// </summary>
+/// <returns>
+/// Returns true if there is a next item.
+/// </returns>
+bool MgdFeatureSetReader::ReadNext()
+{
+ CHECKNULL(m_set, L"MgdFeatureSetReader.ReadNext");
+
+ bool foundNextFeature = false;
+
+ INT32 cnt = m_set->GetCount();
+
+ if ( m_currRecord < cnt )
+ {
+ m_currRecord++;
+ foundNextFeature = true;
+ }
+
+ return foundNextFeature;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the definition of the object currently being read. If the user
+/// has requested only a subset of the class properties, the class
+/// definition reflects what the user has asked, rather than the full class
+/// definition.
+/// </summary>
+/// <returns>A MgClassDefinition representing the current object
+///</returns>
+MgClassDefinition* MgdFeatureSetReader::GetClassDefinition()
+{
+ CHECKNULL(m_set, L"MgdFeatureSetReader.GetClassDefinition");
+
+ return m_set->GetClassDefinition();
+}
+
+MgClassDefinition* MgdFeatureSetReader::GetClassDefinitionNoXml()
+{
+ //fall back to regular public call in this case
+ return GetClassDefinition();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Returns true if the value of the specified property is null.
+/// </summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns true if the value is null.</returns>
+bool MgdFeatureSetReader::IsNull(CREFSTRING propertyName)
+{
+ bool isNull = false;
+
+ Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)GetProperty(propertyName);
+
+ if (ptrProp != NULL)
+ {
+ isNull = ptrProp->IsNull();
+ }
+
+ return isNull;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Returns true if the value of the specified property is null.
+/// </summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns true if the value is null.</returns>
+bool MgdFeatureSetReader::IsNull(INT32 index)
+{
+ bool isNull = false;
+
+ Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)GetProperty(index);
+
+ if (ptrProp != NULL)
+ {
+ isNull = ptrProp->IsNull();
+ }
+
+ return isNull;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Boolean value of the specified property. No conversion is
+/// performed, thus the property must be a of boolean type the result
+/// is undertermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the Boolean value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+bool MgdFeatureSetReader::GetBoolean(CREFSTRING propertyName)
+{
+ bool retVal = false;
+
+ Ptr<MgBooleanProperty> ptrProp = (MgBooleanProperty*)GetProperty(propertyName, MgPropertyType::Boolean);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Boolean value of the specified property. No conversion is
+/// performed, thus the property must be a of boolean type the result
+/// is undertermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the Boolean value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+bool MgdFeatureSetReader::GetBoolean(INT32 index)
+{
+ bool retVal = false;
+
+ Ptr<MgBooleanProperty> ptrProp = (MgBooleanProperty*)GetProperty(index, MgPropertyType::Boolean);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Byte value of the specified property. No conversion is
+/// performed, thus the property must be a of byte type or the result
+/// is undertermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the Byte value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+BYTE MgdFeatureSetReader::GetByte(CREFSTRING propertyName)
+{
+ BYTE retVal = 0;
+
+ Ptr<MgByteProperty> ptrProp = (MgByteProperty*)GetProperty(propertyName, MgPropertyType::Byte);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Byte value of the specified property. No conversion is
+/// performed, thus the property must be a of byte type or the result
+/// is undertermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the Byte value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+BYTE MgdFeatureSetReader::GetByte(INT32 index)
+{
+ BYTE retVal = 0;
+
+ Ptr<MgByteProperty> ptrProp = (MgByteProperty*)GetProperty(index, MgPropertyType::Byte);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the DTime value of the specified property. No conversion is
+/// performed, thus the property must be a of date type or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the DTime value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgDateTime* MgdFeatureSetReader::GetDateTime(CREFSTRING propertyName)
+{
+ Ptr<MgDateTimeProperty> ptrProp = (MgDateTimeProperty*)GetProperty(propertyName, MgPropertyType::DateTime);
+ Ptr<MgDateTime> retVal = ptrProp->GetValue();
+
+ return SAFE_ADDREF((MgDateTime*)retVal);
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the DTime value of the specified property. No conversion is
+/// performed, thus the property must be a of date type or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the DTime value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgDateTime* MgdFeatureSetReader::GetDateTime(INT32 index)
+{
+ Ptr<MgDateTimeProperty> ptrProp = (MgDateTimeProperty*)GetProperty(index, MgPropertyType::DateTime);
+ Ptr<MgDateTime> retVal = ptrProp->GetValue();
+
+ return SAFE_ADDREF((MgDateTime*)retVal);
+}
+
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Single value of the specified property. No conversion is
+/// performed, thus the property must be a of type single or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the single value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+float MgdFeatureSetReader::GetSingle(CREFSTRING propertyName)
+{
+ float retVal = 0;
+
+ Ptr<MgSingleProperty> ptrProp = (MgSingleProperty*)GetProperty(propertyName, MgPropertyType::Single);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Single value of the specified property. No conversion is
+/// performed, thus the property must be a of type single or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the single value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+float MgdFeatureSetReader::GetSingle(INT32 index)
+{
+ float retVal = 0;
+
+ Ptr<MgSingleProperty> ptrProp = (MgSingleProperty*)GetProperty(index, MgPropertyType::Single);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Double value of the specified property. No conversion is
+/// performed, thus the property must be a of type double or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the double value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+double MgdFeatureSetReader::GetDouble(CREFSTRING propertyName)
+{
+ double retVal = 0;
+
+ Ptr<MgDoubleProperty> ptrProp = (MgDoubleProperty*)GetProperty(propertyName, MgPropertyType::Double);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Double value of the specified property. No conversion is
+/// performed, thus the property must be a of type double or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the double value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+double MgdFeatureSetReader::GetDouble(INT32 index)
+{
+ double retVal = 0;
+
+ Ptr<MgDoubleProperty> ptrProp = (MgDoubleProperty*)GetProperty(index, MgPropertyType::Double);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 16 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 16 bits or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the integer 16 bits value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+INT16 MgdFeatureSetReader::GetInt16(CREFSTRING propertyName)
+{
+ INT16 retVal = 0;
+
+ Ptr<MgInt16Property> ptrProp = (MgInt16Property*)GetProperty(propertyName, MgPropertyType::Int16);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 16 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 16 bits or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the integer 16 bits value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+INT16 MgdFeatureSetReader::GetInt16(INT32 index)
+{
+ INT16 retVal = 0;
+
+ Ptr<MgInt16Property> ptrProp = (MgInt16Property*)GetProperty(index, MgPropertyType::Int16);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 32 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 32 bits or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the integer 32 bits value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+INT32 MgdFeatureSetReader::GetInt32(CREFSTRING propertyName)
+{
+ INT32 retVal = 0;
+
+ Ptr<MgInt32Property> ptrProp = (MgInt32Property*)GetProperty(propertyName, MgPropertyType::Int32);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 32 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 32 bits or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the integer 32 bits value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+INT32 MgdFeatureSetReader::GetInt32(INT32 index)
+{
+ INT32 retVal = 0;
+
+ Ptr<MgInt32Property> ptrProp = (MgInt32Property*)GetProperty(index, MgPropertyType::Int32);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 64 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 64 bits or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the integer 64 bits value.
+/// Note: INT64 is actually a pointer to an Integer64 object
+///</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+INT64 MgdFeatureSetReader::GetInt64(CREFSTRING propertyName)
+{
+ INT64 retVal = 0;
+
+ Ptr<MgInt64Property> ptrProp = (MgInt64Property*)GetProperty(propertyName, MgPropertyType::Int64);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 64 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 64 bits or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the integer 64 bits value.
+/// Note: INT64 is actually a pointer to an Integer64 object
+///</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+INT64 MgdFeatureSetReader::GetInt64(INT32 index)
+{
+ INT64 retVal = 0;
+
+ Ptr<MgInt64Property> ptrProp = (MgInt64Property*)GetProperty(index, MgPropertyType::Int64);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the string value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+STRING MgdFeatureSetReader::GetString(CREFSTRING propertyName)
+{
+ STRING retVal = L"";
+
+ Ptr<MgStringProperty> ptrProp = (MgStringProperty*)GetProperty(propertyName, MgPropertyType::String);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the string value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+STRING MgdFeatureSetReader::GetString(INT32 index)
+{
+ STRING retVal = L"";
+
+ Ptr<MgStringProperty> ptrProp = (MgStringProperty*)GetProperty(index, MgPropertyType::String);
+ retVal = ptrProp->GetValue();
+
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the BLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type BLOBs or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the BLOB value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgByteReader* MgdFeatureSetReader::GetBLOB(CREFSTRING propertyName)
+{
+ Ptr<MgBlobProperty> ptrProp = (MgBlobProperty*)GetProperty(propertyName, MgPropertyType::Blob);
+ return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the BLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type BLOBs or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the BLOB value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgByteReader* MgdFeatureSetReader::GetBLOB(INT32 index)
+{
+ Ptr<MgBlobProperty> ptrProp = (MgBlobProperty*)GetProperty(index, MgPropertyType::Blob);
+ return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the CLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type CLOB or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the CLOB value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgByteReader* MgdFeatureSetReader::GetCLOB(CREFSTRING propertyName)
+{
+ Ptr<MgClobProperty> ptrProp = (MgClobProperty*)GetProperty(propertyName, MgPropertyType::Clob);
+ return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the CLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type CLOB or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the CLOB value.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgByteReader* MgdFeatureSetReader::GetCLOB(INT32 index)
+{
+ Ptr<MgClobProperty> ptrProp = (MgClobProperty*)GetProperty(index, MgPropertyType::Clob);
+ return ptrProp->GetValue();
+}
+
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the FeatureReader to access this object value.
+/// The property must be of an object type{} otherwise, the result is NULL.
+/// </summary>
+/// <param name="propertyName">Input the property name.</param>
+/// <returns>Returns the feature reader to access this object.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgFeatureReader* MgdFeatureSetReader::GetFeatureObject(CREFSTRING propertyName)
+{
+ Ptr<MgFeatureProperty> ptrProp = (MgFeatureProperty*)GetProperty(propertyName, MgPropertyType::Feature);
+ return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the FeatureReader to access this object value.
+/// The property must be of an object type{} otherwise, the result is NULL.
+/// </summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the feature reader to access this object.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgFeatureReader* MgdFeatureSetReader::GetFeatureObject(INT32 index)
+{
+ Ptr<MgFeatureProperty> ptrProp = (MgFeatureProperty*)GetProperty(index, MgPropertyType::Feature);
+ return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the geometry value of the specified property as a GeometryReader.
+/// Because no conversion is performed, the property must be
+/// of Geometric type{} otherwise, the result is NULL.</summary>
+/// <param name="propertyName">Input the property name.</param>
+/// <returns>Returns the Geometry object.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgByteReader* MgdFeatureSetReader::GetGeometry(CREFSTRING propertyName)
+{
+ Ptr<MgGeometryProperty> ptrProp = (MgGeometryProperty*)GetProperty(propertyName, MgPropertyType::Geometry);
+ return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the geometry value of the specified property as a GeometryReader.
+/// Because no conversion is performed, the property must be
+/// of Geometric type{} otherwise, the result is NULL.</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the Geometry object.</returns>
+/// EXCEPTIONS:
+/// InvalidPropertyType
+MgByteReader* MgdFeatureSetReader::GetGeometry(INT32 index)
+{
+ Ptr<MgGeometryProperty> ptrProp = (MgGeometryProperty*)GetProperty(index, MgPropertyType::Geometry);
+ return ptrProp->GetValue();
+}
+
+// Get the property for the specified name
+MgProperty* MgdFeatureSetReader::GetProperty(CREFSTRING propertyName, INT16 expectedType)
+{
+ Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)this->GetProperty(propertyName);
+ CHECKNULL(ptrProp, L"MgdFeatureSetReader.GetProperty");
+
+ if (ptrProp->IsNull())
+ {
+ MgStringCollection arguments;
+ arguments.Add(propertyName);
+
+ throw new MgNullPropertyValueException(L"MgdFeatureSetReader.GetProperty",
+ __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ INT16 propType = ptrProp->GetPropertyType();
+ CHECK_PROPERTY_TYPE(propType, expectedType, L"MgdFeatureSetReader.GetProperty");
+
+ return SAFE_ADDREF(ptrProp.p);
+}
+
+// Get the property for the specified index
+MgProperty* MgdFeatureSetReader::GetProperty(INT32 index, INT16 expectedType)
+{
+ Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)this->GetProperty(index);
+ CHECKNULL(ptrProp, L"MgdFeatureSetReader.GetProperty");
+
+ if (ptrProp->IsNull())
+ {
+ STRING buffer;
+ MgUtil::Int32ToString(index, buffer);
+ MgStringCollection arguments;
+ arguments.Add(buffer);
+
+ throw new MgNullPropertyValueException(L"MgdFeatureSetReader.GetProperty",
+ __LINE__, __WFILE__, &arguments, L"", NULL);
+ }
+
+ INT16 propType = ptrProp->GetPropertyType();
+ CHECK_PROPERTY_TYPE(propType, expectedType, L"MgdFeatureSetReader.GetProperty");
+
+ return SAFE_ADDREF(ptrProp.p);
+}
+
+// Get the property for the specified name
+MgProperty* MgdFeatureSetReader::GetProperty(CREFSTRING propertyName)
+{
+ CHECKNULL(m_set, L"MgdFeatureSetReader.GetProperty");
+ CHECK_FEATURESET_COUNT(m_set, L"MgdFeatureSetReader.GetProperty");
+
+ Ptr<MgPropertyCollection> ptrCol = m_set->GetFeatureAt(m_currRecord-1);
+ CHECKNULL(ptrCol, L"MgdFeatureSetReader.GetProperty");
+
+ Ptr<MgProperty> ptrProp = ptrCol->GetItem(propertyName);
+ CHECKNULL(ptrProp, L"MgdFeatureSetReader.GetProperty");
+
+ return SAFE_ADDREF(ptrProp.p);
+}
+
+// Get the property for the specified index
+MgProperty* MgdFeatureSetReader::GetProperty(INT32 index)
+{
+ CHECKNULL(m_set, L"MgdFeatureSetReader.GetProperty");
+ CHECK_FEATURESET_COUNT(m_set, L"MgdFeatureSetReader.GetProperty");
+
+ Ptr<MgPropertyCollection> ptrCol = m_set->GetFeatureAt(m_currRecord-1);
+ CHECKNULL(ptrCol, L"MgdFeatureSetReader.GetProperty");
+
+ Ptr<MgProperty> ptrProp = ptrCol->GetItem(index);
+ CHECKNULL(ptrProp, L"MgdFeatureSetReader.GetProperty");
+
+ return SAFE_ADDREF(ptrProp.p);
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Serialize data to TCP/IP stream
+///</summary>
+///<param name="stream">
+/// Stream
+///</param>
+
+void MgdFeatureSetReader::Serialize(MgStream* stream)
+{
+ NOT_IMPLEMENTED(L"MgdFeatureSetReader::Serialize");
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Deserialize data from TCP/IP stream
+///</summary>
+///<param name="stream">
+/// Stream
+///</param>
+
+void MgdFeatureSetReader::Deserialize(MgStream* stream)
+{
+ NOT_IMPLEMENTED(L"MgdFeatureSetReader::Deserialize");
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Serializes all features into an XML.
+/// XML is serialized from the current position of feature reader in the order
+/// data are retrieved.
+/// <returns>MgByteReader holding XML.</returns>
+MgByteReader* MgdFeatureSetReader::ToXml()
+{
+ string xmlStr;
+ this->ToXml(xmlStr);
+
+ Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)xmlStr.c_str(), (INT32)xmlStr.length());
+ byteSource->SetMimeType(MgMimeType::Xml);
+
+ return byteSource->GetReader();
+}
+
+void MgdFeatureSetReader::ToXml(string &str)
+{
+ CHECKNULL(m_set, L"MgdFeatureSetReader.ToXml");
+
+ Ptr<MgClassDefinition> classDef = this->GetClassDefinition();
+
+ if (classDef != NULL)
+ {
+ // TODO: define a schema for this XML
+ // TODO: rename FeatureSet element to avoid conflict with FeatureSet-1.0.0.xsd?
+ str += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ str += "<FeatureSet>";
+ classDef->ToXml(str);
+ str += "<Features>";
+ while ( this->ReadNext() )
+ {
+ Ptr<MgPropertyCollection> propCol = m_set->GetFeatureAt(m_currRecord-1);
+ INT32 cnt = propCol->GetCount();
+ if (propCol != NULL && cnt > 0)
+ {
+ propCol->ToFeature(str);
+ }
+ }
+ str += "</Features>";
+ str += "</FeatureSet>";
+ }
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Releases all the resources of feature reader.
+/// This must be called when user is done with Feature Reader
+/// <returns>Nothing</returns>
+void MgdFeatureSetReader::Close()
+{
+}
+
+/// <summary>Gets the raster object of the specified property.
+/// the property must be of Raster type; otherwise, an exception is thrown.
+/// </summary>
+/// <param name="propertyName">Input the property name.</param>
+/// <returns>Returns the raster object.</returns>
+MgRaster* MgdFeatureSetReader::GetRaster(CREFSTRING propertyName)
+{
+ NOT_IMPLEMENTED(L"MgdFeatureSetReader::GetRaster");
+}
+
+/// <summary>Gets the raster object of the specified property.
+/// the property must be of Raster type; otherwise, an exception is thrown.
+/// </summary>
+/// <param name="index">Input the property index.</param>
+/// <returns>Returns the raster object.</returns>
+MgRaster* MgdFeatureSetReader::GetRaster(INT32 index)
+{
+ NOT_IMPLEMENTED(L"MgdFeatureSetReader::GetRaster");
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Geometry for the specified property. No conversion is
+/// performed, thus the property must be a of type Geometry or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns a ByteReader object</returns>
+BYTE_ARRAY_OUT MgdFeatureSetReader::GetGeometry(CREFSTRING propertyName, INT32& length)
+{
+ throw new MgNotImplementedException(L"MgdFeatureSetReader.GetGeometry",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Geometry for the specified property. No conversion is
+/// performed, thus the property must be a of type Geometry or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns a ByteReader object</returns>
+BYTE_ARRAY_OUT MgdFeatureSetReader::GetGeometry(INT32 index, INT32& length)
+{
+ throw new MgNotImplementedException(L"MgdFeatureSetReader.GetGeometry",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the string value.</returns>
+const wchar_t* MgdFeatureSetReader::GetString(CREFSTRING propertyName, INT32& length)
+{
+ STRING str = this->GetString(propertyName);
+ length = (INT32)str.size();
+
+ return str.c_str();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the string value.</returns>
+const wchar_t* MgdFeatureSetReader::GetString(INT32 index, INT32& length)
+{
+ STRING str = this->GetString(index);
+ length = (INT32)str.size();
+
+ return str.c_str();
+}
+
+MgFeatureSet* MgdFeatureSetReader::GetFeatures(INT32 count)
+{
+ throw new MgNotImplementedException(L"MgdFeatureSetReader.GetFeatures",
+ __LINE__, __WFILE__, NULL, L"", NULL);
+}
+
+INT32 MgdFeatureSetReader::GetReaderType() { return MgReaderType::FeatureReader; }
\ No newline at end of file
Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.h (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureSetReader.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -0,0 +1,134 @@
+#ifndef DESKTOP_FEATURE_SET_READER_H
+#define DESKTOP_FEATURE_SET_READER_H
+
+class MgdFeatureSetReader : public MgFeatureReader
+{
+ DECLARE_CLASSNAME(MgdFeatureSetReader);
+
+INTERNAL_API:
+ MgdFeatureSetReader(MgFeatureSet* featureSet);
+
+EXTERNAL_API:
+ virtual ~MgdFeatureSetReader();
+
+ //MgReader
+PUBLISHED_API:
+ virtual bool ReadNext();
+
+ virtual bool IsNull(CREFSTRING propertyName);
+
+ virtual bool GetBoolean(CREFSTRING propertyName);
+
+ virtual BYTE GetByte(CREFSTRING propertyName);
+
+ virtual MgDateTime* GetDateTime(CREFSTRING propertyName);
+
+ virtual float GetSingle(CREFSTRING propertyName);
+
+ virtual double GetDouble(CREFSTRING propertyName);
+
+ virtual INT16 GetInt16(CREFSTRING propertyName);
+
+ virtual INT32 GetInt32(CREFSTRING propertyName);
+
+ virtual INT64 GetInt64(CREFSTRING propertyName);
+
+ virtual STRING GetString(CREFSTRING propertyName);
+
+ virtual MgByteReader* GetBLOB(CREFSTRING propertyName);
+
+ virtual MgByteReader* GetCLOB(CREFSTRING propertyName);
+
+ virtual MgByteReader* GetGeometry(CREFSTRING propertyName);
+
+ virtual MgRaster* GetRaster(CREFSTRING propertyName);
+
+ virtual bool IsNull(INT32 index);
+
+ virtual bool GetBoolean(INT32 index);
+
+ virtual BYTE GetByte(INT32 index);
+
+ virtual MgDateTime* GetDateTime(INT32 index);
+
+ virtual float GetSingle(INT32 index);
+
+ virtual double GetDouble(INT32 index);
+
+ virtual INT16 GetInt16(INT32 index);
+
+ virtual INT32 GetInt32(INT32 index);
+
+ virtual INT64 GetInt64(INT32 index);
+
+ virtual STRING GetString(INT32 index);
+
+ virtual MgByteReader* GetBLOB(INT32 index);
+
+ virtual MgByteReader* GetCLOB(INT32 index);
+
+ virtual MgByteReader* GetGeometry(INT32 index);
+
+ virtual MgRaster* GetRaster(INT32 index);
+
+ virtual void Close();
+
+ virtual INT32 GetReaderType();
+
+EXTERNAL_API:
+
+ virtual MgByteReader* ToXml();
+
+INTERNAL_API:
+
+ virtual const wchar_t* GetString(CREFSTRING propertyName, INT32& length);
+
+ virtual const wchar_t* GetString(INT32 index, INT32& length);
+
+ virtual void Serialize(MgStream* stream);
+
+ virtual void Deserialize(MgStream* stream);
+
+ void ToXml(string &str);
+
+ void AssignFeatureSet(MgFeatureSet* featureSet);
+
+ //MgFeatureReader
+PUBLISHED_API:
+ virtual MgClassDefinition* GetClassDefinition();
+
+ virtual MgFeatureReader* GetFeatureObject(CREFSTRING propertyName);
+
+ virtual MgFeatureReader* GetFeatureObject(INT32 index);
+
+INTERNAL_API:
+
+ virtual BYTE_ARRAY_OUT GetGeometry(CREFSTRING propertyName, INT32& length);
+
+ virtual BYTE_ARRAY_OUT GetGeometry(INT32 index, INT32& length);
+
+INTERNAL_API:
+
+ virtual MgClassDefinition* GetClassDefinitionNoXml();
+
+ virtual MgFeatureSet* GetFeatures(INT32 count);
+
+ MgByteReader* GetRaster(STRING rasterPropName, INT32 xSize, INT32 ySize);
+
+protected:
+ virtual void Dispose() { delete this; }
+
+private:
+ MgProperty* GetProperty(CREFSTRING propertyName, INT16 expectedType);
+ /// Get the property for the specified name
+ MgProperty* GetProperty(CREFSTRING propertyName);
+
+ MgProperty* GetProperty(INT32 index, INT16 expectedType);
+ /// Get the property at the specified index
+ MgProperty* GetProperty(INT32 index);
+
+ Ptr<MgFeatureSet> m_set;
+ INT32 m_currRecord;
+};
+
+#endif
\ No newline at end of file
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.cpp 2012-07-15 15:04:11 UTC (rev 6902)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.cpp 2012-07-15 16:59:27 UTC (rev 6903)
@@ -3430,4 +3430,73 @@
}
break;
}
-}
\ No newline at end of file
+}
+
+FdoIdentifierCollection* MgFeatureUtil::ExtractIdentifiers(FdoExpression* expr)
+{
+ CHECKNULL(expr, L"MgFeatureUtil.ExtractIdentifiers");
+
+ FdoPtr<FdoIdentifierCollection> ret;
+ MG_FEATURE_SERVICE_TRY()
+
+ ret = FdoIdentifierCollection::Create();
+
+ switch(expr->GetExpressionType())
+ {
+ case FdoExpressionItemType_ComputedIdentifier:
+ {
+ FdoComputedIdentifier* comp = static_cast<FdoComputedIdentifier*>(expr);
+ FdoPtr<FdoExpression> inner = comp->GetExpression();
+
+ FdoPtr<FdoIdentifierCollection> result = ExtractIdentifiers(inner);
+ for (FdoInt32 i = 0; i < result->GetCount(); i++)
+ {
+ FdoPtr<FdoIdentifier> resultItem = result->GetItem(i);
+ ret->Add(resultItem);
+ }
+ }
+ break;
+ case FdoExpressionItemType_Function:
+ {
+ FdoFunction* func = static_cast<FdoFunction*>(expr);
+ FdoExpressionCollection* funcArgs = func->GetArguments();
+ for (FdoInt32 i = 0; i < funcArgs->GetCount(); i++)
+ {
+ FdoPtr<FdoExpression> arg = funcArgs->GetItem(i);
+ FdoPtr<FdoIdentifierCollection> result = ExtractIdentifiers(arg);
+ for (FdoInt32 j = 0; j < result->GetCount(); j++)
+ {
+ FdoPtr<FdoIdentifier> resultItem = result->GetItem(j);
+ ret->Add(resultItem);
+ }
+ }
+ }
+ break;
+ case FdoExpressionItemType_Identifier:
+ ret->Add(static_cast<FdoIdentifier*>(expr));
+ break;
+ case FdoExpressionItemType_UnaryExpression:
+ {
+ FdoUnaryExpression* unexpr = static_cast<FdoUnaryExpression*>(expr);
+ FdoExpression* inner = unexpr->GetExpression();
+
+ FdoPtr<FdoIdentifierCollection> result = ExtractIdentifiers(inner);
+ for (FdoInt32 i = 0; i < result->GetCount(); i++)
+ {
+ FdoPtr<FdoIdentifier> resultItem = result->GetItem(i);
+ ret->Add(resultItem);
+ }
+ }
+ break;
+ case FdoExpressionItemType_SubSelectExpression:
+ {
+ FdoSubSelectExpression* subSelect = static_cast<FdoSubSelectExpression*>(expr);
+ FdoPtr<FdoIdentifier> propName = subSelect->GetPropertyName();
+ ret->Add(propName);
+ }
+ break;
+ }
+
+ MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgServerFeatureUtil.ExtractIdentifiers")
+ return ret.Detach();
+}
Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.h 2012-07-15 15:04:11 UTC (rev 6902)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureUtil.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -115,6 +115,7 @@
static MgClassDefinition* CloneMgClassDefinition(MgClassDefinition* classDef);
static MgFeatureSchema* CloneMgSchema(MgFeatureSchema* schema);
static void UpdateFdoPropertyValue(FdoPropertyValue* fp, MgProperty* prop);
+ static FdoIdentifierCollection* ExtractIdentifiers(FdoExpression* expr);
private:
static bool Initialize();
Deleted: branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h 2012-07-15 15:04:11 UTC (rev 6902)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h 2012-07-15 16:59:27 UTC (rev 6903)
@@ -1,92 +0,0 @@
-//
-// Copyright (C) 2004-2011 by Autodesk, Inc.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of version 2.1 of the GNU Lesser
-// General Public License as published by the Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-#ifndef MG_FEATURE_NUMERIC_FUNCTIONS_H_
-#define MG_FEATURE_NUMERIC_FUNCTIONS_H_
-
-class MgDisposable;
-class FdoFunction;
-class MgReader;
-class MgFeatureDistribution;
-
-class MgFeatureNumericFunctions : public MgFeatureDistribution
-{
- DECLARE_CLASSNAME(MgFeatureNumericFunctions)
-
-public:
-
- MgFeatureNumericFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
- virtual ~MgFeatureNumericFunctions();
- virtual MgReader* Execute();
- virtual void Dispose()
- {
- delete this;
- }
-
-protected:
-
- MgFeatureNumericFunctions();
-
-private:
-
- void Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
-
- void CalculateDistribution(VECTOR& values, VECTOR& distValues);
- // do not call this method for other functions than MINIMUM, MAXIMUM, UNIQUE
- void CalculateDistribution(VECTOR_INT64& values, VECTOR_INT64& distValues);
- MgReader* GetReader(VECTOR& distValues);
-
-
- // Distribution methods
- void GetEqualCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues);
- void GetStandardDeviationCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues);
- void GetQuantileCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues );
-
- // Jenk methods
- void GetJenksCategories(VECTOR &inputData, int numPartsRequested, double dataMin, double dataMax, VECTOR &distValues);
- bool FixGroups(const std::vector<double>& data, std::vector<int>& indices);
- bool FixDuplicateIndices(std::vector<int>& indices);
- bool FixIndicesByValue(const std::vector<double>& data, std::vector<int>& indices);
- bool doubles_equal(double d1, double d2);
-
- // Single row methods
- void GetMeanValue(VECTOR &values, VECTOR &distValues);
- void GetStandardDeviation(VECTOR &values, VECTOR &distValues);
- void GetUniqueValue(VECTOR &values, VECTOR &distValues);
- void GetUniqueValue(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
- void GetMinimum(VECTOR &values, VECTOR &distValues);
- void GetMinimum(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
- void GetMaximum(VECTOR &values, VECTOR &distValues);
- void GetMaximum(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
-
- // Utility methods
- bool IsInf(double x);
- bool IsNan(double x);
-
- void CheckSupportedPropertyType();
- double GetValue();
-
-private:
-
- STRING m_propertyName;
- INT16 m_type;
- Ptr<MgReader> m_reader;
- FdoPtr<FdoFunction> m_customFunction;
- STRING m_propertyAlias;
-};
-
-#endif
More information about the mapguide-commits
mailing list