///////////////////////////////////////////////////////////////////// // // namespace GwsCommonFdoUtils // ///////////////////////////////////////////////////////////////////// void GwsCommonFdoUtils::GetClassDefinition ( FdoIConnection * pConn, const GWSQualifiedName & classname, FdoFeatureSchema * & schema, FdoClassDefinition * & classDef ) { FdoPtr<FdoIDescribeSchema> descSchema = (FdoIDescribeSchema *) pConn->CreateCommand (FdoCommandType_DescribeSchema); FdoString* schemaName = classname.Schema(); FdoString* clsName = classname.Name(); if (NULL != schemaName && ::wcslen(schemaName) > 0) { descSchema->SetSchemaName(schemaName); } if (NULL != clsName && ::wcslen(clsName) > 0) { FdoPtr<FdoStringCollection> classNames = FdoStringCollection::Create(); classNames->Add(clsName); descSchema->SetClassNames(classNames.p); } FdoPtr <FdoFeatureSchemaCollection> schemas = (FdoFeatureSchemaCollection *) descSchema->Execute (); schema = (FdoFeatureSchema *)schemas->GetItem (schemaName); FdoPtr<FdoClassCollection> pClasses = schema->GetClasses(); classDef = pClasses->GetItem(clsName); }
// Returns an FDO expression engine configured with the custom functions // defined by stylization. FdoExpressionEngine* ExpressionHelper::GetExpressionEngine(Renderer* renderer, RS_FeatureReader* reader) { // get the user-defined functions FdoPtr<FdoExpressionEngineFunctionCollection> userDefinedFunctions = ExpressionHelper::GetExpressionEngineFunctions(renderer, reader); // create the engine FdoPtr<FdoIFeatureReader> fdoReader = reader? reader->GetInternalReader() : NULL; FdoPtr<FdoClassDefinition> classDef = fdoReader? fdoReader->GetClassDefinition() : FdoClass::Create(); FdoExpressionEngine* exec = FdoExpressionEngine::Create(fdoReader, classDef, userDefinedFunctions); // now that we have the engine, set it on the functions that need it - for now // this is only the IF function for (int i=0; i<userDefinedFunctions->GetCount(); ++i) { FdoPtr<FdoExpressionEngineIFunction> func = userDefinedFunctions->GetItem(i); ExpressionFunctionIf* funcIf = dynamic_cast<ExpressionFunctionIf*>(func.p); if (funcIf) { funcIf->SetExpressionEngine(exec); break; } } return exec; }
GWSExtendedFeatureId GwsCommonFdoUtils::MakeFeatureId ( const GWSQualifiedName & classname, FdoPtr<FdoPropertyValueCollection> ident, const wchar_t * ltname ) { static_cast<void>(&(ltname)); // For "unreferenced formal parameter" warning static GWSExtendedFeatureId s_fid; try { CGwsDataValueCollection * keyvals = NULL; keyvals = (CGwsDataValueCollection *) CGwsDataValueCollection::Create (); int size = ident->GetCount (); for (int i = 0; i < size ; i++) { FdoPtr<FdoPropertyValue> propval; FdoPtr<FdoDataValue> value; propval = ident->GetItem (i); value = (FdoDataValue *) propval->GetValue (); keyvals->Add (value); } return GWSExtendedFeatureId (classname, keyvals); } catch (FdoException * e) { assert (false); e->Release (); } return s_fid; }
MgReader* MgSelectCommand::ExecuteJoined(MgStringCollection* idPropNames, bool bForceOneToOne) { Ptr<MgReader> ret; MG_FEATURE_SERVICE_TRY() #ifdef DEBUG_FDO_JOIN FdoPtr<FdoIdentifierCollection> cmdPropNames = m_command->GetPropertyNames(); for (FdoInt32 i = 0; i < cmdPropNames->GetCount(); i++) { FdoPtr<FdoIdentifier> ident = cmdPropNames->GetItem(i); STRING idStr = ident->ToString(); ACE_DEBUG((LM_INFO, ACE_TEXT("\n(%t) [FdoISelect]: (%W)"), idStr.c_str())); } #endif FdoPtr<FdoIFeatureReader> fdoReader = m_command->Execute(); if (bForceOneToOne) { FdoPtr<FdoStringCollection> names = MgServerFeatureUtil::MgToFdoStringCollection(idPropNames, false); FdoPtr<FdoIFeatureReader> forcedReader = new MgFdoForcedOneToOneFeatureReader(fdoReader, names); ret = new MgServerFeatureReader(m_connection, forcedReader, idPropNames); } else { ret = new MgServerFeatureReader(m_connection, fdoReader, idPropNames); } MG_FEATURE_SERVICE_CATCH_AND_THROW(L"MgSelectCommand.ExecuteJoined") return ret.Detach(); }
// // The TRIM function requires special processing. void FdoRdbmsMySqlFilterProcessor::ProcessTrimFunction( FdoFunction& expr) { // Append the function name and the opening bracket. ProcessFunctionName(expr); AppendString( "( " ); // Process the arguments. This is were the special processing is required. // If the call includes an operator (BOTH, LEADING, TRAILING), it is required // to add a FROM clause after the operation keyword. FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for ( int i=0; i<exprCol->GetCount(); i++ ) { FdoPtr<FdoExpression>exp = exprCol->GetItem( i ); if ( (i == 0) && (IsDataValue( exp )) ) { FdoDataValue *dataValue = (static_cast<FdoDataValue *>(exp.p) ); if ( dataValue->GetDataType() == FdoDataType_String ) { FdoStringValue *stringValue = static_cast<FdoStringValue *>(dataValue); AppendString( stringValue->GetString() ); AppendString( " FROM " ); } else throw FdoFilterException::Create(NlsMsgGet(FDORDBMS_29, "Unsupported FDO type in expression")); } else HandleExpr( exp ); } AppendString( " )" ); }
EGwsStatus GwsCommonFdoUtils::DescribeClassSC ( FdoIConnection * conn, const GWSQualifiedName & classname, GwsSpatialContextDescription & desc ) { FdoPtr<FdoFeatureSchema> schema; FdoPtr<FdoClassDefinition> classDef; GwsCommonFdoUtils::GetClassDefinition (conn, classname, schema.p, classDef.p); for (; classDef != NULL ; classDef = classDef->GetBaseClass ()) { FdoPtr<FdoPropertyDefinitionCollection> propdsc = classDef->GetProperties (); // discover geometric property name. Use the first one if there are many. for (int idx = 0; idx < propdsc->GetCount(); idx ++) { FdoPtr<FdoPropertyDefinition> prop; prop = propdsc->GetItem (idx); if (prop->GetPropertyType () == FdoPropertyType_GeometricProperty) { FdoGeometricPropertyDefinition* geomProp = static_cast<FdoGeometricPropertyDefinition*>(prop.p); FdoString* pSC = geomProp->GetSpatialContextAssociation(); if(pSC != NULL) { return GwsCommonFdoUtils::DescribeSC (conn, pSC, desc); } } } } return eGwsSCNotFound; }
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 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); } }
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 MgServerFeatureReader(m_connection, featureReader); }
void SuperMapApplySchemaCommand::DeleteSchema () { TRACE(_T("************SuperMapApplySchemaCommand::DeleteSchema ()")); //获取已经存在的LpSchema FdoPtr<SuperMapLpFeatureSchemaCollection> lpSchemas = mConnection->GetLpSchemas(); FdoPtr<SuperMapLpFeatureSchema> lpSchema = lpSchemas->GetItem(m_Schema->GetName()); //删除LpSchema(自动从LpSchemas collection中移除) lpSchema->Delete(mConnection); }
void SuperMapApplySchemaCommand::ModifySchema () { TRACE(_T("************SuperMapApplySchemaCommand::ModifySchema ()")); //获取已经存在的LpSchema : FdoPtr<SuperMapLpFeatureSchemaCollection> lpSchemas = mConnection->GetLpSchemas(); FdoPtr<SuperMapLpFeatureSchema> lpSchema = lpSchemas->GetItem(m_Schema->GetName()); //通过给定的信息修改模式 lpSchema->Modify(mConnection,m_Schema,m_IgnoreStates); }
void MgFeatureNumericFunctions::Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias) { CHECKNULL((MgReader*)reader, L"MgFeatureNumericFunctions.Initialize"); CHECKNULL((FdoFunction*)customFunction, L"MgFeatureNumericFunctions.Initialize"); if(1 == reader->GetPropertyCount()) { m_type = MgServerFeatureUtil::GetPropertyDefinition(reader, m_propertyName); } else { // Only get the property needed FdoPtr<FdoExpressionCollection> exprCol = customFunction->GetArguments(); FdoInt32 cnt = exprCol->GetCount(); FdoPtr<FdoExpression> expr; if(cnt == 1) { expr = exprCol->GetItem(0); FdoIdentifier* propName = dynamic_cast<FdoIdentifier*>(expr.p); CHECKNULL(propName, L"MgFeatureNumericFunctions.Initialize"); m_propertyName = propName->GetName(); m_type = reader->GetPropertyType(m_propertyName); } else { // Throw original exception m_type = MgServerFeatureUtil::GetPropertyDefinition(reader, m_propertyName); } } // TODO: Should we really check this, may be we can ignore ?? // because we can only come to here if property type is numeric this->CheckSupportedPropertyType(); // We must have an property alias // Though we can name a property with same name as function expression // But Fdo forces to have an alias. Therefore we implement this restriction. if (propertyAlias.empty()) { STRING message = MgServerFeatureUtil::GetMessage(L"MgMissingPropertyAlias"); MgStringCollection arguments; arguments.Add(message); throw new MgFeatureServiceException(L"MgFeatureDistribution.Initialize", __LINE__, __WFILE__, &arguments, L"", NULL); } m_reader = SAFE_ADDREF(reader); m_customFunction = FDO_SAFE_ADDREF(customFunction); m_propertyAlias = propertyAlias; }
void SuperMapConnection::Flush() { TRACE(_T("调用 SuperMapConnection::Flush ...\n")); FdoPtr<SuperMapLpFeatureSchemaCollection> schemas = GetLpSchemas(); int count = schemas->GetCount(); for(int i = 0; i < count; ++i) { FdoPtr<SuperMapLpFeatureSchema> lpSchema = schemas->GetItem(i); FdoPtr<SuperMapLpClassDefinitionCollection> classes = lpSchema->GetLpClasses(); int class_count = classes->GetCount(); for(int j = 0; j < class_count; ++j) { FdoPtr<SuperMapLpClassDefinition> lpClass = classes->GetItem(j); UGC::UGDataset* pDataset = lpClass->GetDataset(); //以同样的方式打开该数据集以使其更新 pDataset->Open(); } } }
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; }
///<summary>Executes the destroy schema command, which removes the schema, class ///definitions, relation definitions, and all instance data from the DataStore. ///If elements in other schemas refer to the schema to be destroyed ///an exception is thrown.</summary> /// <returns>Returns nothing</returns> void ArcSDEDestroySchemaCommand::Execute () { FdoPtr<ArcSDEConnection> connection; // verify the connection connection = static_cast<ArcSDEConnection*>(GetConnection ()); if (connection == NULL) throw FdoException::Create (NlsMsgGet (ARCSDE_CONNECTION_NOT_ESTABLISHED, "Connection not established.")); FdoPtr<FdoIDescribeSchema> describe = (FdoIDescribeSchema*)connection->CreateCommand (FdoCommandType_DescribeSchema); describe->SetSchemaName (mSchemaName->GetName ()); FdoPtr<FdoFeatureSchemaCollection> schemas = describe->Execute (); FdoPtr<FdoFeatureSchema> schema = schemas->GetItem (0); FdoPtr<FdoClassCollection> classes = schema->GetClasses (); // for now, to delete a schema, just delete all the classes for (int i = 0; i < classes->GetCount (); i++) { FdoPtr<FdoClassDefinition> feature = classes->GetItem (i); feature->Delete (); } FdoPtr<FdoIApplySchema> apply = (FdoIApplySchema*)connection->CreateCommand (FdoCommandType_ApplySchema); apply->SetFeatureSchema (schema); apply->Execute (); }
FdoStringCollection * CGwsPreparedFeatureQuery::GetOrderBy () { FdoPtr<FdoIdentifierCollection> ordering = ((FdoISelect *) m_pCommand.p)->GetOrdering (); FdoStringCollection * orderBy = NULL; if(NULL == ordering) return NULL; for (int i = 0; i < ordering->GetCount (); i ++) { FdoPtr<FdoIdentifier> ident = ordering->GetItem (i); if (orderBy == NULL) { orderBy = FdoStringCollection::Create (); } orderBy->Add (ident->GetText ()); } return orderBy; }
void FdoRdbmsMySqlFilterProcessor::ProcessToInt32Int64Function (FdoFunction& expr) { // MySQL uses a different native function name for the expression functions // TOINT32, TOINT64. AppendString(MYSQL_FUNCTION_TONUM); AppendString(OPEN_PARENTH); FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for(int i=0; i<exprCol->GetCount(); i++ ) { if( i!= 0 ) AppendString( L", " ); FdoPtr<FdoExpression>exp = exprCol->GetItem( i ); HandleExpr( exp ); } // Add the keyword that performs the conversion and the closing bracket. AppendString( L", SIGNED)" ); }
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; }
void FdoRdbmsMySqlFilterProcessor::ProcessCurrentDateFunction (FdoFunction& expr) { // MySQL uses a different native function name for the expression function // CurrentDate. AppendString(MYSQL_FUNCTION_CURRENTDATE); AppendString(OPEN_PARENTH); // Note, that the function does not allow any arguments. However, if some // are given, they are added to the function call and it is left to MySQL // to deal with it. FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for(int i=0; i<exprCol->GetCount(); i++ ) { if( i!= 0 ) AppendString( L", " ); FdoPtr<FdoExpression>exp = exprCol->GetItem( i ); HandleExpr( exp ); } AppendString( CLOSE_PARENTH ); }
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; }
IGWSExtendedFeatureDescription * CGwsQueryResultDescriptors::GetItem ( const GWSQualifiedName & name ) { IGWSExtendedFeatureDescription * res = NULL; if (m_classname == name) { AddRef (); res = this; } for (int i = 0; res == NULL && i < GetCount (); i ++) { FdoPtr<IGWSExtendedFeatureDescription> fdesc = GetItem (i); try { res = fdesc->GetItem (name); } catch (IGWSException* pex) { // eat failed to describe. this is expected in join case if(eGwsFailedToDesribeClass != pex->GetStatus()) throw; } } if (res == NULL) GWS_THROW (eGwsFailedToDesribeClass); return res; }
// // Aggregate functions require special processing because of the optional // first parameter. The value of this parameter may be ALL or DISTINCT. void FdoRdbmsMySqlFilterProcessor::ProcessAggregateFunction (FdoFunction& expr) { // Append the function name and the opening bracket. ProcessFunctionName(expr); AppendString( "( " ); // Process the arguments. This is were the special processing is required as // it is required to have the parameters listed sequencially without a comma // between them. FdoPtr<FdoExpressionCollection> exprCol = expr.GetArguments(); for (int i=0; i<exprCol->GetCount(); i++) { FdoPtr<FdoExpression>exp = exprCol->GetItem(i); if ((i == 0) && (IsDataValue(exp))) { FdoDataValue *dataValue = (static_cast<FdoDataValue *>(exp.p)); if (dataValue->GetDataType() == FdoDataType_String) { // Omit ALL if specified as this keyword is not supported in // MySQL. FdoStringValue *stringValue = static_cast<FdoStringValue *>(dataValue); FdoStringP strValue = stringValue->GetString(); if (FdoCommonOSUtil::wcsicmp(strValue, L"ALL") != 0) { AppendString(stringValue->GetString()); AppendString(L" "); } } else throw FdoFilterException::Create(NlsMsgGet(FDORDBMS_29, "Unsupported FDO type in expression")); } else HandleExpr(exp); } AppendString(" )"); }
void FdoSchemaRollbackTest::CreateElectricSchema( FdoIConnection* connection ) { FdoPtr<FdoIDescribeSchema> pDescCmd = (FdoIDescribeSchema*) connection->CreateCommand(FdoCommandType_DescribeSchema); pDescCmd->SetSchemaName( L"Acad" ); FdoPtr<FdoFeatureSchemaCollection> pAcadSchema = pDescCmd->Execute(); FdoPtr<FdoClassDefinition> pEntClass = FdoClassesP(FdoFeatureSchemaP(pAcadSchema->GetItem( L"Acad" ))->GetClasses())->GetItem( L"Entity" ); FdoPtr<FdoIApplySchema> pCmd = (FdoIApplySchema*) connection->CreateCommand(FdoCommandType_ApplySchema); /* A schema with dictionary */ FdoPtr<FdoFeatureSchema> pSchema = FdoFeatureSchema::Create( L"Electric'l", L"Electrical '' schema'" ); pAcadSchema->Add( pSchema ); FdoSADP(pSchema->GetAttributes())->Add( L"'Author", L"Thomas O'Edison" ); /* An abstract base class */ FdoPtr<FdoFeatureClass> pDevClass = FdoFeatureClass::Create( L"ElectricDevice", L"electic base class" ); pDevClass->SetIsAbstract(true); FdoPtr<FdoDataPropertyDefinition> pProp = FdoDataPropertyDefinition::Create( L"FeatId", L"id" ); pProp->SetDataType( FdoDataType_Int64 ); pProp->SetNullable(false); pProp->SetIsAutoGenerated(true); FdoPropertiesP(pDevClass->GetProperties())->Add( pProp ); FdoDataPropertiesP(pDevClass->GetIdentityProperties())->Add( pProp ); // Test nested object properties (ElectricDevice.graphic.xdata) where graphic's class has an id. FdoPtr<FdoObjectPropertyDefinition> pObjProp = FdoObjectPropertyDefinition::Create( L"graphic", L"Acad entity" ); pObjProp->SetObjectType( FdoObjectType_Value ); pObjProp->SetClass( pEntClass ); FdoPropertiesP(pDevClass->GetProperties())->Add( pObjProp ); // Test geometry property FdoPtr<FdoGeometricPropertyDefinition> pGeomProp = FdoGeometricPropertyDefinition::Create( L"Geometry", L"location and shape" ); pGeomProp->SetGeometryTypes( FdoGeometricType_Point | FdoGeometricType_Curve ); FdoPropertiesP(pDevClass->GetProperties())->Add( pGeomProp ); pDevClass->SetGeometryProperty( pGeomProp ); FdoClassesP(pSchema->GetClasses())->Add( pDevClass ); /* Subclass with dictionary */ FdoPtr<FdoFeatureClass> pClass = FdoFeatureClass::Create( L"Transformer", L"" ); pClass->SetIsAbstract(false); pClass->SetBaseClass( pDevClass ); FdoSADP(pClass->GetAttributes())->Add( L"Rules' DLL", L"transformer.dll" ); FdoSADP(pClass->GetAttributes())->Add( L"Entrypoint", L"start_transformer" ); // Add data properties of various types pProp = FdoDataPropertyDefinition::Create( L"Voltage", L"voltage" ); FdoSADP(pProp->GetAttributes())->Add( L"Calculable", L"yes" ); pProp->SetDataType( FdoDataType_Decimal ); pProp->SetPrecision(10); pProp->SetScale(2); pProp->SetNullable(false); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); pProp = FdoDataPropertyDefinition::Create( L"Phase", L"A, B or C" ); pProp->SetDataType( FdoDataType_String ); pProp->SetLength(1); pProp->SetNullable(false); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); pProp = FdoDataPropertyDefinition::Create( L"InstallDate", L"" ); pProp->SetDataType( FdoDataType_DateTime ); pProp->SetNullable(true); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); pProp = FdoDataPropertyDefinition::Create( L"LastInspectDate", L"" ); pProp->SetDataType( FdoDataType_DateTime ); pProp->SetNullable(true); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); pProp = FdoDataPropertyDefinition::Create( L"LastRepairDate", L"" ); pProp->SetDataType( FdoDataType_DateTime ); pProp->SetNullable(true); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); pProp = FdoDataPropertyDefinition::Create( L"PartNum", L"" ); pProp->SetDataType( FdoDataType_Int16 ); pProp->SetNullable(true); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); pProp = FdoDataPropertyDefinition::Create( L"Volume", L"" ); pProp->SetDataType( FdoDataType_Single ); pProp->SetNullable(false); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); FdoClassesP(pSchema->GetClasses())->Add( pClass ); pClass = FdoFeatureClass::Create( L"Conductor", L"" ); pClass->SetIsAbstract(false); pClass->SetBaseClass( pDevClass ); pProp = FdoDataPropertyDefinition::Create( L"underground", L"" ); pProp->SetDataType( FdoDataType_Boolean ); pProp->SetNullable(false); FdoPropertiesP(pClass->GetProperties())->Add( pProp ); FdoClassesP(pSchema->GetClasses())->Add( pClass ); pCmd->SetFeatureSchema( pSchema ); pCmd->Execute(); }
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; } }
FdoRdbmsFeatureReader *FdoRdbmsSelectCommand::GetOptimizedFeatureReader( const FdoSmLpClassDefinition *classDefinition ) { // Verify if this is a special case we can optimize (no grouping filter, // and only aggregate functions Count() and/or SpatialExtents()) FdoRdbmsFeatureReader *reader = NULL; bool bOtherAggrSelected = false; aggr_list *selAggrList = new aggr_list; if ( (classDefinition->GetClassType() == FdoClassType_FeatureClass ) && mIdentifiers && !mGroupingCol) { for (int i = 0; i < mIdentifiers->GetCount() && !bOtherAggrSelected; i++ ) { FdoPtr<FdoIdentifier> identifier = mIdentifiers->GetItem(i); FdoComputedIdentifier* computedIdentifier = dynamic_cast<FdoComputedIdentifier*>(identifier.p); if (computedIdentifier) { FdoPtr<FdoExpression> expr = computedIdentifier->GetExpression(); FdoFunction* func = dynamic_cast<FdoFunction*>(expr.p); if (func && 0==FdoCommonOSUtil::wcsicmp(func->GetName(), FDO_FUNCTION_SPATIALEXTENTS)) { FdoPtr<FdoExpressionCollection> args = func->GetArguments(); FdoPtr<FdoExpression> arg = args->GetItem(0); FdoIdentifier* argId = dynamic_cast<FdoIdentifier*>(arg.p); AggregateElement *id = new AggregateElement; id->propName = argId->GetName(); id->name = computedIdentifier->GetName(); id->type = FdoPropertyType_GeometricProperty; selAggrList->push_back( id ); } else if (func && 0 == FdoCommonOSUtil::wcsicmp(func->GetName(), FDO_FUNCTION_COUNT)) { // Only if the argument count for the function is 1 do some // special handling. FdoPtr<FdoExpressionCollection> exprArgColl = func->GetArguments(); if (exprArgColl->GetCount() == 1) { AggregateElement *id = new AggregateElement; id->name = computedIdentifier->GetName(); id->type = FdoPropertyType_DataProperty; selAggrList->push_back( id ); } else { bOtherAggrSelected = true; } } else { bOtherAggrSelected = true; } } } } // Now perform the actual select aggregates and return the data reader: if ( !bOtherAggrSelected && ( selAggrList->size() > 0 )) { reader = mFdoConnection->GetOptimizedAggregateReader( classDefinition, selAggrList, GetFilterRef() ); // The reader takes ownership of the selAggrList } else { // Sorry, no optimization. Clean up. for ( size_t j = 0; j < selAggrList->size(); j++ ) delete selAggrList->at(j); delete selAggrList; } return reader; }
//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); } //} } }
/* Test spatial filter. */ void BasicUpdateTests::spatial_filter () { if (CreateSchemaOnly()) return; try { mConnection = ArcSDETests::GetConnection (); mConnection->SetConnectionString (ArcSDETestConfig::ConnStringMetadcovSingleDb()); mConnection->Open (); // Clean up previous tests: CleanUpClass(mConnection, ArcSDETestConfig::ClassSchemaTestClassComplex(), ArcSDETestConfig::ClassNameTestClassComplex(), true); FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert); insert->SetFeatureClassName (ArcSDETestConfig::QClassNameTestClassComplex()); FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues (); FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)FdoExpression::Parse (Data[0]->mPropertyData[0]); FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (Data[0]->mPropertyName, expression); values->Add (value); expression = (FdoValueExpression*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5010.282 5011.717, 5010.4 5011.7, 5010.4 5011.3, 5010.282 5011.717))')"); value = FdoPropertyValue::Create ((FdoString*)GetGeomPropName(), expression); values->Add (value); FdoPtr<FdoIFeatureReader> reader = insert->Execute (); int id1; while (reader->ReadNext ()) id1 = reader->GetInt32 ((FdoString*)GetIdPropName()); reader->Close(); value = values->GetItem (Data[0]->mPropertyName); expression = (FdoValueExpression*)FdoExpression::Parse (L"'John Smith'"); value->SetValue (expression); value = values->GetItem ((FdoString*)GetGeomPropName()); expression = (FdoValueExpression*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5000.919 5000.277, 5000.5 5000.2, 5000.5 5000.7, 5000.919 5000.277))')"); value->SetValue (expression); reader = insert->Execute (); int id2; while (reader->ReadNext ()) id2 = reader->GetInt32 ((FdoString*)GetIdPropName()); reader->Close(); value = values->GetItem (Data[0]->mPropertyName); expression = (FdoValueExpression*)FdoExpression::Parse (L"'Mott the Hoople'"); value->SetValue (expression); value = values->GetItem ((FdoString*)GetGeomPropName()); expression = (FdoValueExpression*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5014.262 5015.018, 5014.3 5015.9, 5014.9 5015.9, 5014.262 5015.018))')"); value->SetValue (expression); reader = insert->Execute (); int id3; while (reader->ReadNext ()) id3 = reader->GetInt32 ((FdoString*)GetIdPropName()); reader->Close(); // do a spatial filtered update FdoPtr<FdoIUpdate> update = (FdoIUpdate*)mConnection->CreateCommand (FdoCommandType_Update); update->SetFeatureClassName (ArcSDETestConfig::QClassNameTestClassComplex()); update->SetFilter (FdoPtr<FdoFilter>(FdoFilter::Parse (L"SHAPE INTERSECTS GEOMFROMTEXT ('POLYGON XY (( 5012 5012, 5020 5012, 5020 5016, 5012 5016, 5012 5012 ))')"))); values = update->GetPropertyValues (); expression = (FdoValueExpression*)FdoExpression::Parse (L"'Alice in Wonderland'"); value = FdoPropertyValue::Create (Data[0]->mPropertyName, expression); values->Add (value); if (1 != update->Execute ()) CPPUNIT_FAIL ("update execute failed"); // check by doing a select FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select); select->SetFeatureClassName (ArcSDETestConfig::QClassNameTestClassComplex()); reader = select->Execute (); int id; while (reader->ReadNext ()) { id = reader->GetInt32 ((FdoString*)GetIdPropName()); FdoString* item = reader->GetString (Data[0]->mPropertyName); if (id == id3) CPPUNIT_ASSERT_MESSAGE ("value not changed", 0 == wcscmp (item, L"Alice in Wonderland")); else CPPUNIT_ASSERT_MESSAGE ("value mistakenly changed", 0 != wcscmp (item, L"Alice in Wonderland")); } reader->Close(); // Clean up after test: CleanUpClass(mConnection, ArcSDETestConfig::ClassSchemaTestClassComplex(), ArcSDETestConfig::ClassNameTestClassComplex(), true); } catch (FdoException* ge) { fail (ge); } }
MgPropertyCollection* MgdUpdateFeaturesCommand::ExecuteInsert(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues, MgTransaction* trans) { Ptr<MgPropertyCollection> ret; MG_FEATURE_SERVICE_TRY() CHECK_FEATURE_SOURCE_ARGUMENT(resource, L"MgdUpdateFeaturesCommand::ExecuteInsert"); CHECKARGUMENTNULL(batchPropertyValues, L"MgdUpdateFeaturesCommand::ExecuteInsert"); if (className.empty()) throw new MgNullArgumentException(L"MgdUpdateFeaturesCommand::ExecuteInsert", __LINE__, __WFILE__, NULL, L"", NULL); ret = new MgPropertyCollection(); Ptr<MgdFeatureConnection> connWrap; FdoPtr<FdoIConnection> conn; FdoPtr<FdoITransaction> fdoTrans; Ptr<MgdTransaction> mgTrans = dynamic_cast<MgdTransaction*>(trans); if (NULL != mgTrans) { SAFE_ADDREF(mgTrans.p); Ptr<MgResourceIdentifier> origFeatureSource = mgTrans->GetFeatureSource(); //Check that the transaction originates from the same feature source if (origFeatureSource->ToString() != resource->ToString()) throw new MgInvalidArgumentException(L"MgdUpdateFeaturesCommand::ExecuteInsert", __LINE__, __WFILE__, NULL, L"", NULL); connWrap = mgTrans->GetConnection(); //Connection is already open fdoTrans = mgTrans->GetFdoTransaction(); } else { connWrap = new MgdFeatureConnection(resource); } conn = connWrap->GetConnection(); FdoPtr<FdoIInsert> insert = (FdoIInsert*)conn->CreateCommand(FdoCommandType_Insert); insert->SetFeatureClassName(className.c_str()); FdoPtr<FdoPropertyValueCollection> propVals = insert->GetPropertyValues(); if (NULL != fdoTrans.p) insert->SetTransaction(fdoTrans); //TODO: Support batch parameters, the main beneficiary of this API. Even then, //the value flipping approach employed here has performance benefits for certain //providers, like SQLite for (INT32 i = 0; i < batchPropertyValues->GetCount(); i++) { Ptr<MgPropertyCollection> propertyValues = batchPropertyValues->GetItem(i); //First feature, set up the FDO property value collection if (i == 0) { for (INT32 i = 0; i < propertyValues->GetCount(); i++) { Ptr<MgProperty> mgp = propertyValues->GetItem(i); FdoPtr<FdoPropertyValue> pv = MgdFeatureUtil::MgPropertyToFdoProperty(mgp); propVals->Add(pv); } } else //Feature after the first { //Set all to null for (INT32 i = 0; i < propVals->GetCount(); i++) { FdoPtr<FdoPropertyValue> fp = propVals->GetItem(i); FdoPtr<FdoValueExpression> expr = fp->GetValue(); FdoDataValue* fdv = dynamic_cast<FdoDataValue*>(expr.p); FdoGeometryValue* fgv = dynamic_cast<FdoGeometryValue*>(expr.p); if (fdv) { fdv->SetNull(); } else if (fgv) { fgv->SetNullValue(); } } //Now set the appropriate values. MgdFeatureUtil does the work for (INT32 i = 0; i < propertyValues->GetCount(); i++) { Ptr<MgNullableProperty> mgp = (MgNullableProperty*)propertyValues->GetItem(i); if (!mgp->IsNull()) { FdoPtr<FdoPropertyValue> fp = propVals->GetItem(mgp->GetName().c_str()); MgdFeatureUtil::UpdateFdoPropertyValue(fp, mgp); } } } STRING sIndex; MgUtil::Int32ToString(i, sIndex); //Insert and stash the result in the property collection FdoPtr<FdoIFeatureReader> insertRes = insert->Execute(); Ptr<MgFeatureReader> fr = new MgdFeatureReader(connWrap, insertRes); Ptr<MgFeatureProperty> fp = new MgFeatureProperty(sIndex, fr); ret->Add(fp); } MG_FEATURE_SERVICE_CATCH_AND_THROW_WITH_FEATURE_SOURCE(L"MgdUpdateFeaturesCommand::ExecuteInsert", resource) return ret.Detach(); }
/* Test geometry update operation. */ void BasicUpdateTests::geometry_update () { if (CreateSchemaOnly()) return; try { mConnection = ArcSDETests::GetConnection (); mConnection->SetConnectionString (ArcSDETestConfig::ConnStringMetadcovSingleDb()); mConnection->Open (); // Clean up previous tests: CleanUpClass(mConnection, ArcSDETestConfig::ClassSchemaTestClassComplex(), ArcSDETestConfig::ClassNameTestClassComplex(), true); FdoPtr<FdoIInsert> insert = (FdoIInsert*)mConnection->CreateCommand (FdoCommandType_Insert); insert->SetFeatureClassName (ArcSDETestConfig::QClassNameTestClassComplex()); // misnomer, it's not a feature class FdoPtr<FdoPropertyValueCollection> values = insert->GetPropertyValues (); FdoPtr<FdoValueExpression> expression = (FdoValueExpression*)FdoExpression::Parse (Data[0]->mPropertyData[0]); FdoPtr<FdoPropertyValue> value = FdoPropertyValue::Create (Data[0]->mPropertyName, expression); values->Add (value); expression = (FdoValueExpression*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5010.282 5011.717, 5011 5012, 5013 5012, 5010.282 5011.717))')"); FdoPtr<FdoPropertyValue> geometry = FdoPropertyValue::Create ((FdoString*)GetGeomPropName(), expression); values->Add (geometry); FdoPtr<FdoIFeatureReader> reader = insert->Execute (); int id; while (reader->ReadNext ()) id = reader->GetInt32 ((FdoString*)GetIdPropName()); reader->Close(); value = values->GetItem (Data[0]->mPropertyName); expression = (FdoValueExpression*)FdoExpression::Parse (L"'John Smith'"); value->SetValue (expression); value = values->GetItem ((FdoString*)GetGeomPropName()); expression = (FdoValueExpression*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5000.919 5000.277, 5005 5000, 5005 5005, 5000.919 5000.277))')"); value->SetValue (expression); reader = insert->Execute (); int id2; while (reader->ReadNext ()) id2 = reader->GetInt32 ((FdoString*)GetIdPropName()); reader->Close(); value = values->GetItem (Data[0]->mPropertyName); expression = (FdoValueExpression*)FdoExpression::Parse (L"'Mott the Hoople'"); value->SetValue (expression); value = values->GetItem ((FdoString*)GetGeomPropName()); expression = (FdoValueExpression*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5014.262 5000.018, 5015 5005, 5016 5010, 5014.262 5000.018))')"); value->SetValue (expression); reader = insert->Execute (); int id3; while (reader->ReadNext ()) id3 = reader->GetInt32 ((FdoString*)GetIdPropName()); reader->Close(); // update it FdoPtr<FdoIUpdate> update = (FdoIUpdate*)mConnection->CreateCommand (FdoCommandType_Update); update->SetFeatureClassName (ArcSDETestConfig::QClassNameTestClassComplex()); FdoPtr<FdoPropertyValueCollection> propertyValues = update->GetPropertyValues(); wchar_t filter[1024]; FdoCommonOSUtil::swprintf(filter, ELEMENTS(filter), L"%ls = %d", (FdoString*)GetIdPropName(), id); FdoPtr<FdoFilter> fdoFilter = FdoFilter::Parse (filter); update->SetFilter (fdoFilter); values = update->GetPropertyValues (); expression = (FdoValueExpression*)FdoExpression::Parse (L"GeomFromText('POLYGON XY ((5008.8 5004.7, 5010 5010, 5000 5005, 5008.8 5004.7))')"); value = FdoPropertyValue::Create ((FdoString*)GetGeomPropName(), expression); values->Add (value); if (1 != update->Execute ()) CPPUNIT_FAIL ("update execute failed"); // check by doing a select FdoPtr<FdoISelect> select = (FdoISelect*)mConnection->CreateCommand (FdoCommandType_Select); select->SetFeatureClassName (ArcSDETestConfig::QClassNameTestClassComplex()); fdoFilter = FdoFilter::Parse (filter); select->SetFilter (fdoFilter); reader = select->Execute (); while (reader->ReadNext ()) { FdoPtr<FdoGeometryValue> geometry = FDO_SAFE_ADDREF((FdoGeometryValue*)expression.p); FdoPtr<FdoByteArray> fetched = reader->GetGeometry ((FdoString*)GetGeomPropName()); FdoString* referenceText = geometry->ToString(); FdoPtr<FdoGeometryValue> fetchedGeom = FdoGeometryValue::Create (fetched); const wchar_t* fetchedText = fetchedGeom->ToString (); CPPUNIT_ASSERT_MESSAGE ("incorrect geometry value", 0==wcscmp(referenceText, fetchedText)); } reader->Close(); // Clean up after test: CleanUpClass(mConnection, ArcSDETestConfig::ClassSchemaTestClassComplex(), ArcSDETestConfig::ClassNameTestClassComplex(), true); } catch (FdoException* ge) { fail (ge); } }