void CGwsPreparedFeatureQuery::PrepareInternal () { CGwsFdoCommand::PrepareNonKeyProperties (); if(m_selectList->GetCount() > 0) { //add in the select ilst, along with the identity properties, revision number WSTRARRAY strNames; bool bFoundRevision = false; for (FdoInt32 idx = 0; m_identity != NULL && idx < m_identity->GetCount(); idx ++) { FdoPtr<FdoDataPropertyDefinition> pPropdef = m_identity->GetItem(idx); FdoString* pName = pPropdef->GetName(); bool bFound = false; for (int i = 0; i < m_selectList->GetCount(); i++) { FdoPtr<FdoIdentifier> selProp = m_selectList->GetItem(i); FdoString * selectName = selProp->GetName(); if(wcscmp(pName,selectName) == 0) bFound = true; if(idx==0 && wcscmp(m_revisionprop.c_str (), selectName) == 0) bFoundRevision = true; } if(!bFound) strNames.push_back(pName); } if(!bFoundRevision && !m_revisionprop.empty()) strNames.push_back(m_revisionprop.c_str()); FdoPtr<FdoIdentifierCollection> lst = ((FdoIBaseSelect*)m_pCommand.p)->GetPropertyNames(); if (lst != NULL) { lst->Clear(); if(!m_bIsSelectDistinct) { //add identity properties for (unsigned int i = 0; i < strNames.size(); i++) { FdoPtr<FdoIdentifier> pIdent = FdoIdentifier::Create (strNames[i].c_str()); lst->Add(pIdent); } } for (int i = 0; i < m_selectList->GetCount(); i++) { FdoPtr<FdoIdentifier> pIdent = m_selectList->GetItem(i); lst->Add(pIdent); } } } }
void CGwsQueryResultDescriptors::appendPropertyNames ( FdoIdentifierCollection * propnamestoadd, FdoClassDefinition * classDef, FdoStringCollection * propnames, std::vector<CGwsPropertyDesc> & propdsc ) { FdoPtr<FdoPropertyDefinitionCollection> properties; FdoPtr<FdoClassDefinition> baseClass = classDef->GetBaseClass (); if (baseClass != NULL) { appendPropertyNames (propnamestoadd, baseClass, propnames, propdsc); } properties = classDef->GetProperties (); if (properties == NULL) return; for (int i = 0; i < properties->GetCount (); i ++) { FdoPtr<FdoPropertyDefinition> pFdoProperty = properties->GetItem (i); if (propnamestoadd == NULL || propnamestoadd->IndexOf (pFdoProperty->GetName ()) >= 0) pushPropDefinition (pFdoProperty, propnames,propdsc); } }
void GwsBinaryFeatureWriter::WriteAssociationProperty(FdoAssociationPropertyDefinition* apd, FdoIFeatureReader* reader) { if( apd->GetIsReadOnly() ) return; FdoPtr<FdoDataPropertyDefinitionCollection> idents = apd->GetIdentityProperties(); if( idents->GetCount() == 0 ) { // Search for property values with names build from the association property name and the // associated class identity properties. For example if the associated class identifier is "Id" and the // association property name is "AssocProp", then we should search for a property value with // name: "AssocProp.Id". If that property value is found and set, then that means an association // exists between the new object(we are about to insert) and the object identified by the value // of the property value(AssocProp.Id) FdoPtr<FdoClassDefinition> cls = apd->GetAssociatedClass(); idents = cls->GetIdentityProperties(); } if( reader->IsNull( apd->GetName() ) ) return; FdoPtr<FdoIFeatureReader> loc_reader = reader->GetFeatureObject( apd->GetName() ); if( ! loc_reader->ReadNext() ) return; for(int i=0; i<idents->GetCount(); i++ ) { FdoPtr<FdoDataPropertyDefinition> prop = idents->GetItem( i ); if( ! loc_reader->IsNull( prop->GetName() ) ) WriteProperty( prop, loc_reader); } }
void FdoImportExportTest::Test8 () { try { FdoIoStreamP configStream = FdoIoMemoryStream::Create(); CreateConfigBadWkt( configStream ); // Test 8 tries adding a spatial context whose WKT differs // from what Oracle defines for its coordinate system. // This test should fail for Oracle and pass for the others. printf( "Test8 (junk WKT) ... \n" ); printf( "\tOpening Source Connection ... \n" ); FdoPtr<FdoIConnection> connection = UnitTestUtil::CreateConnection( true, true, DB_NAME_SRC_SUFFIX, NULL, NULL, 0 ); FdoPtr<FdoIConnectionCapabilities> cap = connection->GetConnectionCapabilities(); // Import from the input XML document printf( "\tImporting ...\n" ); Import( connection, configStream, NULL, true, false ); FdoPtr<FdoIGetSpatialContexts> cmd = (FdoIGetSpatialContexts*) connection->CreateCommand( FdoCommandType_GetSpatialContexts ); cmd->SetActiveOnly(false); FdoPtr<FdoISpatialContextReader> reader = cmd->Execute(); while ( reader->ReadNext() ) { // Skip default spatial context if not writing it. if ( wcscmp(reader->GetName(), L"Manhole1") == 0 ) { if ( cap->SupportsCSysWKTFromCSysName() ) CPPUNIT_ASSERT( wcscmp(reader->GetCoordinateSystemWkt(), L"LOCAL_CS [ \"Non-Earth (Meter)\", LOCAL_DATUM [\"Local Datum\", 0], UNIT [\"Meter\", 1.0], AXIS [\"X\", EAST], AXIS[\"Y\", NORTH]]") == 0 ); else CPPUNIT_ASSERT( wcscmp(reader->GetCoordinateSystemWkt(), L"nonsense wkt") == 0 ); } } } catch ( FdoException* e ) { UnitTestUtil::FailOnException( e ); } printf( "Done\n" ); }
bool GwsCommonFdoUtils::GetGeometryName (FdoClassDefinition *pClassDef, std::wstring &name) { if(pClassDef == NULL) return false; if(pClassDef->GetClassType() == FdoClassType_FeatureClass) { FdoFeatureClass* pFeatClass = dynamic_cast<FdoFeatureClass*>(pClassDef); if(!pFeatClass) { assert(false); return false; } FdoPtr<FdoGeometricPropertyDefinition> pgDef = pFeatClass->GetGeometryProperty(); if (pgDef != NULL) { name = pgDef->GetName(); return true; } } FdoInt32 idx; FdoPtr<FdoClassDefinition> classDef = pClassDef; FDO_SAFE_ADDREF(pClassDef); for (; classDef != NULL ; classDef = classDef->GetBaseClass ()) { FdoPtr<FdoPropertyDefinitionCollection> propdsc = classDef->GetProperties (); // discover geometric property name. Use the first one if there are many. for (idx = 0; idx < propdsc->GetCount(); idx ++) { FdoPtr<FdoPropertyDefinition> prop; prop = propdsc->GetItem(idx); if (prop->GetPropertyType () == FdoPropertyType_GeometricProperty) { name = prop->GetName (); return true; } } } return false; }
WSTR GwsCommonFdoUtils::GetRevisionProperty (FdoClassDefinition * classdef) { WSTR revision; // discover revision property. Revision property is defined // for a given class FdoPtr<FdoReadOnlyPropertyDefinitionCollection> pBaseProperties = classdef->GetBaseProperties(); // See if property with this name already exists: for (int idx=0; pBaseProperties != NULL && idx < pBaseProperties->GetCount(); idx++) { FdoPtr<FdoPropertyDefinition> pBaseProperty; pBaseProperty = (FdoPropertyDefinition*)pBaseProperties->GetItem(idx); if (! _wcsicmp (pBaseProperty->GetName(), REVISIONNUMBER_PROPNAME)) { revision = pBaseProperty->GetName(); break; } } return revision; }
EGwsStatus GwsCommonFdoUtils::DescribeSC ( FdoIConnection * conn, FdoString * scname, GwsSpatialContextDescription & scdesc ) { FdoPtr<FdoIGetSpatialContexts> cmd; FdoPtr<FdoISpatialContextReader> reader; scdesc.SetClassName (GWSQualifiedName ()); scdesc.SetPropertyName (NULL); scdesc.SetSpatialContextName (NULL); scdesc.SetSpatialContextDesc (NULL); scdesc.SetCsNameWkt (NULL); if (scname == NULL || * scname == 0) return eGwsOk; try { cmd = (FdoIGetSpatialContexts *) conn->CreateCommand (FdoCommandType_GetSpatialContexts); reader = cmd->Execute (); while (reader->ReadNext ()) { if (wcscmp (reader->GetName (), scname) == 0) { FdoString * cswkt = reader->GetCoordinateSystemWkt (); FdoString * desc = reader->GetDescription (); double xytol = reader->GetXYTolerance(); scdesc.SetCsNameWkt (cswkt); scdesc.SetSpatialContextDesc (desc); scdesc.SetSpatialContextName (scname); scdesc.SetXYTolerance(xytol); FdoPtr<FdoByteArray> pByteArray = reader->GetExtent(); if (pByteArray) { FdoPtr<FdoFgfGeometryFactory> pAwkbFactory = FdoFgfGeometryFactory::GetInstance(); FdoPtr<FdoIGeometry> pGeometry = pAwkbFactory->CreateGeometryFromFgf(pByteArray); FdoPtr<FdoIEnvelope> pEnvelope = pGeometry->GetEnvelope(); scdesc.SetExtents (pEnvelope); } return eGwsOk; } } return eGwsSCNotFound; } catch (FdoException * fdoEx) { fdoEx->Release (); } // in case when exception thrown, assume that sc are not // supported. return eGwsNotSupported; }
bool GwsBinaryFeatureWriter::WriteAssociationProperty(FdoAssociationPropertyDefinition* apd, FdoPropertyValueCollection* pvc) { bool errorIfSet = apd->GetIsReadOnly(); bool oneIdentIsNull = false; bool written = false; FdoPtr<FdoDataPropertyDefinitionCollection> idents = apd->GetIdentityProperties(); if( idents->GetCount() == 0 ) { // Search for property values with names build from the association property name and the // associated class identity properties. For example if the associated class identifier is "Id" and the // association property name is "AssocProp", then we should search for a property value with // name: "AssocProp.Id". If that property value is found and set, then that means an association // exists between the new object(we are about to insert) and the object identified by the value // of the property value(AssocProp.Id) FdoPtr<FdoClassDefinition> cls = apd->GetAssociatedClass(); idents = cls->GetIdentityProperties(); } for(int i=0; i<idents->GetCount(); i++ ) { FdoPtr<FdoDataPropertyDefinition> prop = idents->GetItem( i ); std::wstring wstr = apd->GetName(); wstr += L"."; wstr += prop->GetName(); FdoPtr<FdoPropertyValue> pv = pvc->FindItem( wstr.c_str() ); if(pv != NULL) { if( errorIfSet ) GWS_THROW(eGwsFailed); //cannot add readonly association property value if( oneIdentIsNull ) GWS_THROW(eGwsFailed); //one of the identity properties is null WriteProperty(prop, pv, true); written = true; oneIdentIsNull = false; } else { if( written ) // we already written one or more identity and this one is null GWS_THROW(eGwsFailed); oneIdentIsNull = true; } } return written; }
void CGwsFlatGwsIterator::DescribeFeature(IGWSExtendedFeatureDescription ** ppResDesc) { if (ppResDesc == NULL) GWS_THROW (eGwsNullPointer); if (m_fdsc == NULL) { FdoPtr<FdoClassDefinition> classDef = GetClassDefinition (); CGwsQueryResultDescriptors * resdsc = new CGwsQueryResultDescriptors (classDef, classDef->GetName (), NULL, NULL, true, NULL); resdsc->AddRef (); m_fdsc = resdsc; } * ppResDesc = m_fdsc; if (* ppResDesc) (* ppResDesc)->AddRef (); }
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 SpatialContextTest::testXmlNesting() { try { // Create an XML document with Spatial Contexts nested 2 levels down from // root element. FdoIoMemoryStreamP stream = FdoIoMemoryStream::Create(); FdoXmlWriterP writer = FdoXmlWriter::Create( stream ); // Create 2 Level1 elements under the root element. writer->WriteStartElement( L"Level1" ); writer->WriteStartElement( L"Level2" ); writer->WriteEndElement(); writer->WriteStartElement( L"Level2" ); writer->WriteEndElement(); writer->WriteEndElement(); // The Spatial Contexts are under the second Level1 element. writer->WriteStartElement( L"Level1" ); // Mix them up with some other elements that should be skipped. writer->WriteStartElement( L"Level2" ); writer->WriteEndElement(); FdoXmlSpatialContextWriterP SCWriter = FdoXmlSpatialContextWriter::Create( writer ); SCWriter->SetName( L"Embedded1" ); FdoByteArray* extent = SerializeExtent( 0, 0, 15000, 10000 ); SCWriter->SetExtent( extent ); extent->Release(); SCWriter->WriteSpatialContext(); SCWriter = NULL; writer->WriteStartElement( L"Level2" ); writer->WriteEndElement(); SCWriter = FdoXmlSpatialContextWriter::Create( writer ); SCWriter->SetName( L"Embedded2" ); extent = SerializeExtent( 0, 0, 15000, 10000 ); SCWriter->SetExtent( extent ); extent->Release(); SCWriter->WriteSpatialContext(); SCWriter = NULL; writer->WriteStartElement( L"Level2" ); writer->WriteEndElement(); writer = NULL; stream->Reset(); FdoIoFileStreamP fileStream = FdoIoFileStream::Create( L"sc_nested.xml", L"w+"); XmlFormatter formatter1(stream, fileStream); formatter1.Format(); stream->Reset(); FdoPtr<NestedReader> reader = NestedReader::Create(stream); // Read the spatial contexts. Should get both of them reader->ReadNext(); FDO_CPPUNIT_ASSERT( wcscmp(reader->GetName(), L"Embedded1") == 0 ); reader->ReadNext(); FDO_CPPUNIT_ASSERT( wcscmp(reader->GetName(), L"Embedded2") == 0 ); // Shouldn't be any more spatial contexts at this point. FDO_CPPUNIT_ASSERT( reader->ReadNext() == false ); } catch ( FdoException* e ) { UnitTestUtil::FailOnException( e ); } }
EGwsStatus CGwsFdoInsertCommand::Execute (CGwsMutableFeature & feat) { Clear (); EGwsStatus fdoes = eGwsOk; if(!m_bIsPrepared) { PushStatus (eGwsFdoCommandIsNotPrepared); return eGwsFdoCommandIsNotPrepared; } try { GetPropertyValues (); // initialize property value collection eGwsOkThrow(SetProperties (feat, true)) ; FdoPtr<FdoIFeatureReader> pReader = ((FdoIInsert*)m_pCommand.p)->Execute(); //!FDO may return null pointer even if the command succeed. So remove the following assert. //assert (pReader != NULL); // Read assigned Id if( pReader != NULL ) { if (pReader->ReadNext()) { // Read the key of just inserted record // CGwsDataValueCollection * keyvals = NULL; for (FdoInt32 idx = 0; m_identity != NULL && idx < m_identity->GetCount (); idx ++) { FdoPtr<FdoDataPropertyDefinition> keyprop = m_identity->GetItem (idx); FdoPtr<FdoDataValue> val = GwsQueryUtils::GetDataPropertyValue (pReader, keyprop->GetDataType (), keyprop->GetName ()); if (val == NULL) continue; if (keyvals == NULL) keyvals = (CGwsDataValueCollection *) CGwsDataValueCollection::Create (); keyvals->Add (val); feat.SetValue (keyprop->GetName (),val); } #ifdef OBJECT_PROPERTIES //insert object property values that were cached in SetProperties() if(!m_objPropNames.empty()) { //Get object property class instance array that was cached in SetProperties() int numProps = m_objPropNames.size(); for( int i = 0; i<numProps; i++) { const std::wstring strPropName = m_objPropNames[i]; const std::wstring objectClassName = acmapFdoUtils::constructObjectClassName(aTOw(m_classname.Class()),strPropName.c_str()); //get the object property values AcMapFdoFeatureIterator* featIter = NULL; eGwsOkThrow(feature.GetFeature(wTOa(strPropName.c_str()),featIter)); assert(featIter != NULL); //insert the primary keys of the parent feature and the object property values eGwsOkThrow(InsertObjectProperties(objectClassName.c_str(), valList, featIter)); } } #endif // long ver; // Read sequence number if (!m_revisionprop.empty()) { FdoInt32 revnum = pReader->GetInt32 (m_revisionprop.c_str ()); feat.SetRevisionNumber (revnum); } feat.SetFeatureId (GWSFeatureId (keyvals)); } pReader->Close(); } } catch(FdoException *e) { PushFdoException (eGwsFailedToExecuteCommand, e); e->Release(); fdoes = eGwsFailedToExecuteCommand; } catch(EGwsStatus es) { PushStatus (es); fdoes = es; } ReleasePropertyValues (); // releases property value collection return fdoes; }
FdoXmlLpSchemaCollection* FdoXmlSchemaManager::_schemas() { if (m_lpSchemas == NULL) { m_lpSchemas = FdoXmlLpSchemaCollection::Create(this); FdoInt32 count = m_fdoSchemas->GetCount(); FdoPtr<FdoPhysicalSchemaMappingCollection> mappings = m_flags->GetSchemaMappings(); if ( mappings == NULL ) mappings = m_fdoSchemas->GetXmlSchemaMappings(); FdoInt32 count1 = mappings->GetCount(); FdoPtr<FdoXmlSchemaMapping> tempXmlMapping = FdoXmlSchemaMapping::Create(L"temp"); for (int i = 0; i < count; i++) { FdoPtr<FdoFeatureSchema> schema = m_fdoSchemas->GetItem(i); FdoPtr<FdoXmlSchemaMapping> mapping = static_cast<FdoXmlSchemaMapping*>(mappings->GetItem(tempXmlMapping->GetProvider(), schema->GetName())); FdoPtr<FdoXmlLpSchema> lpSchema = FdoXmlLpSchema::Create(schema, mapping); m_lpSchemas->Add(lpSchema); } } return m_lpSchemas.p; }
//serializes a collection of property values into a byte array //This function differs from WriteFeature() in that //it will merge property values specified in the given PropertyValueCollection //with property values in the given FeatureReader. The PropertyValueCollection //represents properties to be updated in an old feature record represented by //the given FeatureReader. void GwsBinaryFeatureWriter::WriteFeature(FdoClassDefinition* fc, FdoString* fcName, FdoPropertyValueCollection* pvc, FdoIFeatureReader* reader) { FdoPtr<FdoReadOnlyPropertyDefinitionCollection> bpdc = fc->GetBaseProperties(); FdoPtr<FdoPropertyDefinitionCollection> pdc = fc->GetProperties(); //find number of properties we will store into the data record //we will use this number to save an offset into the data records for each property //at the beginning of the data record int numProps = bpdc->GetCount() + pdc->GetCount();// - idpdc->GetCount(); //now generate the data value -- write all property values, except for the ones //we already wrote to the key -- we have to check if each one is in the ID prop //collection //write feature class ID m_wrtr.WriteString(fcName); int fcNameLen = m_wrtr.GetPosition(); //reserve space for offsets into property values in data record for (int i=0; i<numProps; i++) m_wrtr.WriteInt32(0); int index = 0; //base properties first for (int i=0; i<bpdc->GetCount(); i++) { FdoPtr<FdoPropertyDefinition> pd = (FdoPropertyDefinition*)bpdc->GetItem(i); //save offset of property data to the reserved position at the //beginning of the record //TODO: endian ((int*)(m_wrtr.GetData() + fcNameLen))[index++] = m_wrtr.GetPosition(); //if property is autogenerated, do not write //anything. We use the record number as autogen property value //so we can obtain it at read time //if (!pi->IsPropAutoGen(pd->GetName())) //{ if (pvc) { if( pd->GetPropertyType() == FdoPropertyType_AssociationProperty ) { if( ! WriteAssociationProperty((FdoAssociationPropertyDefinition*)pd.p, pvc) ) WriteAssociationProperty((FdoAssociationPropertyDefinition*)pd.p, reader); } else { FdoPtr<FdoPropertyValue> pv((FdoPropertyValue*)pvc->FindItem(pd->GetName())); if(pv != NULL) WriteProperty(pd, pv); else WriteProperty(pd, reader); } } else { WriteProperty(pd, reader); } //} } //class properties for (int i=0; i<pdc->GetCount(); i++) { FdoPtr<FdoPropertyDefinition> pd = (FdoPropertyDefinition*)pdc->GetItem(i); //save offset of property data to the reserved position at the //beginning of the record //TODO: endian ((int*)(m_wrtr.GetData() + fcNameLen))[index++] = m_wrtr.GetPosition(); //if property is autogenerated, do not write //anything. We use the record number as autogen property value //so we can obtain it at read time //if (!pi->IsPropAutoGen(pd->GetName())) //{ if (pvc) { if( pd->GetPropertyType() == FdoPropertyType_AssociationProperty ) { if( ! WriteAssociationProperty((FdoAssociationPropertyDefinition*)pd.p, pvc) ) WriteAssociationProperty((FdoAssociationPropertyDefinition*)pd.p, reader); } else { FdoPtr<FdoPropertyValue> pv((FdoPropertyValue*)pvc->GetItem(pd->GetName())); if(pv != NULL) WriteProperty(pd, pv); else WriteProperty(pd, reader); } } else { WriteProperty(pd, reader); } //} } }
FdoIFeatureReader *FdoRdbmsSelectCommand::Execute( bool distinct, FdoInt16 callerId ) { if (!mConnection || !mFdoConnection || mFdoConnection->GetConnectionState() != FdoConnectionState_Open) throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_13, "Connection not established")); // Flush out any outstanding modifications before selecting; so that the select // sees a current picture of the RDBMS. mIConnection->Flush(); int qid = -1; bool res = false; bool delStatement = true; GdbiStatement* statement = NULL; const FdoSmLpClassDefinition *classDefinition = mConnection->GetSchemaUtil()->GetClass(this->GetClassNameRef()->GetText()); bool isFeatureClass = ( classDefinition != NULL && classDefinition->GetClassType() == FdoClassType_FeatureClass ); bool isForUpdate = HasLobProperty( classDefinition ); bool doNotUseSimpleSelect = mHasObjectProps && (mIdentifiers == NULL || mIdentifiers->GetCount() == 0); try { // for now we support only select with joins if (callerId == (FdoInt16)FdoCommandType_Select && !doNotUseSimpleSelect && !mHasObjectProps) { FdoPtr<FdoRdbmsSqlBuilder> sqlBuilder = mFdoConnection->GetSqlBuilder(); if (sqlBuilder) { std::vector<NameOrderingPair> ordering; FdoPtr<FdoParameterValueCollection> params = GetParameterValues(); FdoPtr<FdoJoinCriteriaCollection> jcColl = GetJoinCriteria(); sqlBuilder->SetParameterValues(params); if (mOrderingIdentifiers && mOrderingIdentifiers->GetCount()) { for (int i=0; i<mOrderingIdentifiers->GetCount(); i++) { FdoPtr<FdoIdentifier> id = mOrderingIdentifiers->GetItem(i); ordering.push_back(NameOrderingPair(id.p, ((int)mOrderingOptions.size() != mOrderingIdentifiers->GetCount()) ? mOrderingOption : mOrderingOptions[id->GetName()])); } } FdoString* sqlString = sqlBuilder->ToSelectSqlString(GetClassNameRef(), mAliasName, GetFilterRef(), mIdentifiers, ordering, jcColl); if (sqlString != NULL && *sqlString != '\0') { statement = mConnection->GetGdbiConnection()->Prepare( sqlString ); std::vector< std::pair< FdoLiteralValue*, FdoInt64 > >* paramsUsed = sqlBuilder->GetUsedParameterValues(); if (paramsUsed != NULL && paramsUsed->size()) { if (mBindParamsHelper == NULL) mBindParamsHelper = new FdoRdbmsPropBindHelper(mConn); mBindParamsHelper->BindParameters(statement, paramsUsed); } GdbiQueryResult *queryRslt = statement->ExecuteQuery(); delete statement; if (mBindParamsHelper != NULL) mBindParamsHelper->Clear(); // statement will be deleted in the reader. delStatement = false; return FdoRdbmsSimpleFeatureReader::Create(mFdoConnection, queryRslt, isFeatureClass, classDefinition, NULL, mIdentifiers); } } } FdoPtr<FdoRdbmsFilterProcessor>flterProcessor = mFdoConnection->GetFilterProcessor(); FdoPtr<FdoParameterValueCollection> params = GetParameterValues(); flterProcessor->SetParameterValues(params); FdoRdbmsFilterUtilConstrainDef filterConstrain; filterConstrain.distinct = distinct; filterConstrain.orderingOption = mOrderingOption; filterConstrain.selectedProperties = mIdentifiers; filterConstrain.groupByProperties = mGroupingCol; filterConstrain.orderByProperties = mOrderingIdentifiers; // Verify if this is a special case we can optimize (no filter, no grouping filter, // and only aggregate functions Count() and/or SpatialExtents()) FdoRdbmsFeatureReader *reader = GetOptimizedFeatureReader( classDefinition ); if ( reader ) return reader; // FDO supports expression functions that may not have native support in the // underlying system. If this is the case then the request has to be handled // by the Expression Engine. bool isValidFilter = true, isValidSelectList = true; if ( this->GetFilterRef() != NULL ) isValidFilter = flterProcessor->IsValidExpression( this->GetFilterRef() ); isValidSelectList = flterProcessor->IsValidExpression( mIdentifiers ); if ( ( !isValidFilter ) || ( !isValidSelectList ) ) { // Either the selected property list of the the filter is invalid. In any case // create a SQL statement that selects all properties for the current class. // If the filter is valid it is used to narrow the selected amount of data. FdoString *sqlStatement = flterProcessor->FilterToSql( ((isValidFilter) ? this->GetFilterRef() : NULL), this->GetClassNameRef()->GetText() ); GdbiQueryResult *queryRslt = mConnection->GetGdbiConnection()->ExecuteQuery( sqlStatement ); FdoPtr<FdoIFeatureReader> featureReader = new FdoRdbmsFeatureReader( mFdoConnection, queryRslt, isFeatureClass, classDefinition, NULL, NULL, 0, NULL ); // The Expression Engine cannot work with the class definition of type // "FdoSmLpClassDefinition". Instead it is necessary to get the corresponding // definition of type "FdoClassDefinition". This is done next. const FdoSmLpSchema* schema = mConnection->GetSchema( this->GetClassNameRef()->GetText() ); FdoFeatureSchemasP fdoFeatureSchemas = mFdoConnection->GetSchemaManager()->GetFdoSchemas( schema->GetName() ); FdoClassesP classCol = (FdoClassCollection *)fdoFeatureSchemas->FindClass( this->GetClassNameRef()->GetText() ); FdoClassDefinitionP classDef = classCol->GetItem(0); // Create the collection of custom functions. FdoSmLpSchemasP schemas = ((FdoSmLpSchema *) schema)->GetSchemas(); FdoExpressionEngineFunctionCollection *userDefinedFunctions = GetUserDefinedFunctions( schemas->GetSpatialContextMgr()->GetSpatialContexts(), classDef ); return FdoExpressionEngineUtilFeatureReader::Create( classDef, featureReader, this->GetFilterRef(), mIdentifiers, userDefinedFunctions); } // The selected properties and the filter are both valid. Do the normal processing. // Validate the filter if ( this->GetFilterRef() != NULL ) { FdoPtr<FdoIFilterCapabilities> filterCaps = mFdoConnection->GetFilterCapabilities(); FdoExpressionEngine::ValidateFilter( NULL, this->GetFilterRef(), NULL, filterCaps); } // Call FilterToSql just to populate the filter's list of geometric conditions; FdoString * sqlString = flterProcessor->FilterToSql( this->GetFilterRef(), this->GetClassNameRef()->GetText(), SqlCommandType_Select, FdoCommandType_Select, &filterConstrain, isForUpdate, callerId ); FdoPtr<FdoRdbmsFilterProcessor::BoundGeometryCollection> boundGeometries = flterProcessor->GetBoundGeometryValues(); FdoPtr<FdoRdbmsSecondarySpatialFilterCollection> geometricConditions = flterProcessor->GetGeometricConditions(); vector<int> * logicalOps = flterProcessor->GetFilterLogicalOps(); FdoPtr<FdoIdentifierCollection> idsWithGeoms = FdoIdentifierCollection::Create(); if (( mIdentifiers && mIdentifiers->GetCount() > 0) ) { // Make sure that the properties are listed for any geometric conditions that require secondary filtering. if (geometricConditions != NULL) { for (FdoInt32 i=0; i < geometricConditions->GetCount(); i++) { FdoPtr<FdoRdbmsSpatialSecondaryFilter> ssf = geometricConditions->GetItem(i); FdoString * ssfPropertyName = ssf->GetPropertyName(); FdoPtr<FdoIdentifier> ssfId = mIdentifiers->FindItem(ssfPropertyName); if (ssfId == NULL) { // Property wasn't selected by the caller. ssfId = FdoIdentifier::Create(ssfPropertyName); idsWithGeoms->Add(ssfId); } } // Convert to SQL again if we added geometric properties. if (idsWithGeoms->GetCount() > 0) { // Make our own copy of the original list, to avoid a side effect of changing // mIdentifiers, which the user can effectively see. Perserve original order, // effectively creating a new list that appends the geometry names. for (FdoInt32 i = mIdentifiers->GetCount()-1; i >= 0; i--) { FdoPtr<FdoIdentifier> id = mIdentifiers->GetItem(i); idsWithGeoms->Insert(0, id); } filterConstrain.selectedProperties = idsWithGeoms; sqlString = flterProcessor->FilterToSql( this->GetFilterRef(), this->GetClassNameRef()->GetText(), SqlCommandType_Select, FdoCommandType_Select, &filterConstrain, isForUpdate, callerId ); } } if (callerId == FdoCommandType_SelectAggregates) { FdoSchemaManagerP pschemaManager = mConnection->GetSchemaUtil()->GetSchemaManager(); FdoPtr<FdoFeatureSchemaCollection> schemas = pschemaManager->GetFdoSchemas(L""); FdoPtr<FdoCommonExpressionExecutor> expVer = FdoCommonExpressionExecutor::Create(schemas, GetClassNameRef()); FdoPtr<FdoIExpressionCapabilities> expCap = mFdoConnection->GetExpressionCapabilities(); expVer->ValidateIdentifiers(mIdentifiers, expCap); } } statement = mConnection->GetGdbiConnection()->Prepare( sqlString ); std::vector< std::pair< FdoLiteralValue*, FdoInt64 > >* paramsUsed = flterProcessor->GetUsedParameterValues(); if (paramsUsed != NULL && paramsUsed->size()) { if (mBindParamsHelper == NULL) mBindParamsHelper = new FdoRdbmsPropBindHelper(mConn); mBindParamsHelper->BindParameters(statement, paramsUsed); } GdbiQueryResult *queryRslt = statement->ExecuteQuery(); delete statement; if (mBindParamsHelper != NULL) mBindParamsHelper->Clear(); // statement will be deleted in the reader. delStatement = false; // For now only SQL Spatial Server supports SupportsSimpleReader, later (after we add some unit tests) we can extend it to other providers if (!flterProcessor->ContainsCustomObjects() && flterProcessor->SupportsSimpleReader() && geometricConditions == NULL && callerId == (FdoInt16)FdoCommandType_Select && !doNotUseSimpleSelect) { return FdoRdbmsSimpleFeatureReader::Create(mFdoConnection, queryRslt, isFeatureClass, classDefinition, NULL, mIdentifiers); } else { if (( mIdentifiers && mIdentifiers->GetCount() > 0)) return new FdoRdbmsFeatureSubsetReader (mFdoConnection, queryRslt, isFeatureClass, classDefinition, NULL, mIdentifiers, geometricConditions, logicalOps ); else return new FdoRdbmsFeatureReader (mFdoConnection, queryRslt, isFeatureClass, classDefinition, NULL, NULL, 0, geometricConditions, logicalOps ); // The feature reader should free the queryRslt } } catch (FdoCommandException *ex) { if (delStatement) delete statement; ex; SELECT_CLEANUP; throw; } catch (FdoException *ex) { if (delStatement) delete statement; SELECT_CLEANUP; // Wrap in FdoPtr to remove original reference to original exception throw FdoCommandException::Create(ex->GetExceptionMessage(), FdoPtr<FdoException>(ex), ex->GetNativeErrorCode()); } catch ( ... ) { if (delStatement) delete statement; SELECT_CLEANUP; throw; } }