const void* FdoRdbmsSQLDataReader::GetGeometry(FdoInt32 index, FdoInt32* len, bool noExcOnInvalid)
{
    ValidateIndex(index);
    if( ! mHasMoreRows )
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_62, noMoreRows));

    if (mGeomIdx != index)
    {
        FdoIGeometry* geom = NULL;
        bool isSupportedType = false;
        bool isNull = false;

        mGeomIdx = index;
        if (mWkbBuffer)
            *mWkbBuffer = 0;
        mQueryResult->GetBinaryValue (index+1, sizeof(FdoIGeometry *), (char*)&geom, &isNull, NULL);

        if ( !isNull && geom && geom->GetDerivedType() != FdoGeometryType_None )
            isSupportedType = true;

        if ( !isNull && geom != NULL )
        {
            if ( isSupportedType )
            {
                FdoPtr<FdoFgfGeometryFactory>  gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoByteArray> fgf = gf->GetFgf(geom);
                if (fgf != NULL && fgf->GetCount() != 0)
                {
                    mWkbGeomLen = fgf->GetCount();
                    if (mWkbBufferLen < mWkbGeomLen)
                    {
                        delete[] mWkbBuffer;
                        mWkbBufferLen = mWkbGeomLen;
                        mWkbBuffer = new unsigned char[mWkbGeomLen];
                    }
                    memcpy(mWkbBuffer, fgf->GetData(), mWkbGeomLen);
                }
                else
                    mWkbGeomLen = 0;
            }
            else
                mWkbGeomLen = -1;
        }
        else // isNull indicator is not set by dbi_get_val_b for geometry columns
            mWkbGeomLen = 0;
    }
    *len = mWkbGeomLen;
    if (*len <= 0)
    {
        if (noExcOnInvalid)
            return NULL;
        else if (*len == 0)
            throw FdoCommandException::Create(NlsMsgGet1( FDORDBMS_385, "Property '%1$ls' value is NULL; use IsNull method before trying to access the property value", mColList[index].column ));
        else
            throw FdoCommandException::Create( NlsMsgGet(FDORDBMS_116, "Unsupported geometry type" ) );
    }

    return mWkbBuffer;
}
/// <summary>Sets the XML configuration stream used to configure the Data Store. 
/// SetConfiguration can only be called while the connection is closed.</summary>
/// <param name="configStream">Input the XML configuration stream</param> 
/// <returns>Returns nothing</returns> 
void SuperMapConnection::SetConfiguration(FdoIoStream* configStream)
{
	TRACE(_T("!!!调用 SuperMapConnection::SetConfiguration ...\n"));

	throw FdoException::Create(NlsMsgGet(SUPERMAP_CONFIGURATION_FILE_NOT_SUPPORTED, 
		"SuperMap Provider does not support configuration files."));
}
FdoRdbmsLongTransactionReader::FdoRdbmsLongTransactionReader (
                    FdoIConnection                         *a_fdo_connection,
                    FdoString                              *the_lt_name,
                    FdoRdbmsLongTransactionDataRequestType the_query_request)

// +---------------------------------------------------------------------------
// | The function represents a class constructor.
// +---------------------------------------------------------------------------

{

    // Initialize the member variables.

    SetToZero();

    // Assign the given parameters to the corresponding class variables.

    fdo_connection = dynamic_cast<FdoRdbmsConnection*>(a_fdo_connection);
    if (fdo_connection)
        fdo_connection->AddRef();

    if (the_lt_name != NULL)
        if ((lt_name = SetValue(the_lt_name)) == NULL)
             throw FdoCommandException::Create(
                           NlsMsgGet(FDORDBMS_91, "Failed to allocate memory"));
    query_request = the_query_request;

}  //  FdoRdbmsLongTransactionReader ()
//
// 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( " )" );
}
bool FdoRdbmsSQLDataReader::IsNull(FdoInt32 index)
{
    bool isNull = true;
    if( ! mHasMoreRows )
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_62, noMoreRows));
    ValidateIndex(index);

    switch(mColList[index].datatype)
    {
    case RDBI_GEOMETRY:
        {
            FdoInt32 len = 0;
            GetGeometry(index, &len, true);
            isNull = (len == 0);
        }
        break;
    case RDBI_BLOB_ULEN:
    case RDBI_WSTRING_ULEN:
    case RDBI_STRING_ULEN:
        {
            FdoByteArray* arr = NULL;
            bool isNullArr = false;
            mQueryResult->GetBinaryValue (index+1, sizeof(FdoByteArray*), (char*)&arr, &isNullArr, NULL);
            isNull = (isNullArr || arr == NULL || arr->GetCount() == 0);
        }
        break;
    default:
        isNull = mQueryResult->GetIsNull(index+1);
        break;
    }
    return isNull;
}
/// <summary>Gets the 16-bit integer value of the specified property. No conversion is
/// performed, thus the property must be FdoDataType_Int16 or an exception
/// is thrown.</summary>
/// <param name="identifier">Input the property name.</param> 
/// <returns>Returns the FdoInt16 value.</returns> 
FdoInt16 SuperMapFeatureReader::GetInt16 (FdoString* identifier)
{
	if(NULL == m_pRecordset || NULL == identifier)
	{
		return 0;
	}

	UGC::UGString strProperName = SuperMapUtil::WcharToString(identifier).c_str();
	UGC::UGVariant var;
	m_pRecordset->GetFieldValue(strProperName, var);
	if(var.GetType() == UGC::UGVariant::Short) //UGC类库升级后,各个引擎都放在该字段中,统一了
	{
		FdoInt16 ret = (FdoInt16)var.GetValue().sVal;
		return ret;
	}
	//if(var.GetType() == UGC::UGVariant::Integer) //Oracle 短整型放在次变量中
	//{
	//	FdoInt32 ret = (FdoInt16)var.GetValue().iVal;
	//	return ret;
	//}
	else
	{
		throw FdoException::Create(NlsMsgGet(SUPERMAP_UNEXPECTED_DATATYPE, "The field type is not short (%1$ls).", "GetInt16"));
	}
}
const wchar_t* FdoRdbmsSQLDataReader::GetString(FdoInt32 index)
{
    bool isNULL = false;
    if (! mHasMoreRows)
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_62, noMoreRows));
    ValidateIndex(index);

    int i = index;
	if (mSprops[i].valid)
		return mSprops[i].data;

    const wchar_t* tmpVal = NULL;
    if (mColList[index].datatype == RDBI_WSTRING_ULEN)
    {
        FdoByteArray* arr = NULL;
        mQueryResult->GetBinaryValue (index+1, sizeof(FdoByteArray*), (char*)&arr, &isNULL, NULL);
        if (!isNULL && arr != NULL && arr->GetCount() != 0)
        {
            int sizeW = (int)(arr->GetCount()/sizeof(wchar_t));
            mSprops[i].EnsureSize(sizeW + 1);
            memcpy(mSprops[i].data, arr->GetData(), arr->GetCount());
            *(mSprops[i].data+sizeW) = L'\0';
            mSprops[i].valid = 1;
            return mSprops[i].data;
        }
    }
    else if (mColList[index].datatype == RDBI_STRING_ULEN)
    {
        FdoByteArray* arr = NULL;
        mQueryResult->GetBinaryValue (index+1, sizeof(FdoByteArray*), (char*)&arr, &isNULL, NULL);
        if (!isNULL && arr != NULL && arr->GetCount() != 0)
        {
            int cntArr = arr->GetCount();
            mSprops[i].EnsureSize(2*cntArr + 1);
            char* startCh = (char*)(mSprops[i].data+cntArr);
            memcpy(startCh, arr->GetData(), cntArr);
            *(startCh+cntArr) = L'\0'; // add string ending
            ut_utf8_to_unicode(startCh, mSprops[i].data, cntArr+1);
            mSprops[i].valid = 1;
            return mSprops[i].data;
        }
    }
    else
        tmpVal = mQueryResult->GetString(index+1, &isNULL, NULL);

    if (isNULL || tmpVal == NULL)
    {
        mSprops[i].EnsureSize(1);
        mSprops[i].data = L'\0';
        mSprops[i].valid = 1;
        throw FdoCommandException::Create(NlsMsgGet1( FDORDBMS_386, strNUllColumnExp, mColList[index].column ));
    }
    
    size_t sz = wcslen(tmpVal);
    mSprops[i].EnsureSize(sz+1);
    wcscpy(mSprops[i].data, tmpVal);
    mSprops[i].valid = 1;

    return mSprops[i].data;
}
/// <summary>Gets the Single floating point value of the specified property. No
/// conversion is performed, thus the property must be FdoDataType_Single
/// or an exception is thrown.</summary>
/// <param name="identifier">Input the property name.</param> 
/// <returns>Returns the single value</returns> 
float SuperMapFeatureReader::GetSingle (FdoString* identifier)
{
	if(NULL == m_pRecordset || NULL == identifier)
	{
		return 0;
	}

	UGC::UGString strProperName = SuperMapUtil::WcharToString(identifier).c_str();
	UGC::UGVariant var;
	m_pRecordset->GetFieldValue(strProperName, var);
	if(var.GetType() == UGC::UGVariant::Float) //UGC类库升级后,各个引擎都放在该字段中,统一了
	{
		float ret = var.GetValue().fVal;
		return ret;
	}
	//if(var.GetType() == UGC::UGVariant::Double) //Oracle 单精度放在此变量中
	//{
	//	double ret = var.GetValue().dVal;
	//	TRACE(_T("调用 SuperMapFeatureReader::GetSingle[%g] \n"), ret);
	//	return ret;
	//}
	else
	{
		throw FdoException::Create(NlsMsgGet(SUPERMAP_UNEXPECTED_DATATYPE, "The field type is not float (%1$ls).", "GetSingle"));
	}
}
FdoISpatialContextReader* FdoRdbmsGetSpatialContexts::Execute()
{
    FdoRdbmsSpatialContextReader *scReader = 0;

    int                found = false;

    try
    {
        FdoSchemaManagerP smgr = mFdoConnection->GetSchemaManager();

        if ( mActiveOnly )
        {
            FdoString * activeScName = mFdoConnection->GetActiveSpatialContextName();
            if (NULL != activeScName && wcslen(activeScName) > 0)
                found = true;

            if ( !found )
                throw FdoRdbmsException::Create( FdoStringP( NlsMsgGet( FDORDBMS_325,
                                                "Active Spatial Context not found") )
                                                );
        }
        
        scReader = new FdoRdbmsSpatialContextReader(mFdoConnection, mActiveOnly);
    }
    catch (FdoRdbmsException *ex)
    {
       throw ex;
    }

    return scReader;
}
void FdoRdbmsLongTransactionReader::InitialLoad ()

// +---------------------------------------------------------------------------
// | The function issues the query to retrieve the requested information.
// +---------------------------------------------------------------------------

{

    try {

      // Issue the query to retrieve the requested information and keep a
      // reference to the provided query handler.

      lt_query_handler = 
        FdoPtr<FdoRdbmsLongTransactionManager>(fdo_connection->GetLongTransactionManager())->LTQuery(lt_name,
                                                             query_request);

    }  //  try ...

    catch ( ... ) {

      throw FdoCommandException::Create(
                NlsMsgGet(
                    FDORDBMS_356,
                    "Error during initial load of long transaction info data"));

    }  //  catch ...

}  //  InitialLoad ()
///<summary>Executes the ApplySchema command that creates metadata and physical
///storage for the schema. An exception is thrown if the schema already
///exists or if a schema already exists and the feature provider only
///supports a single schema. If schema changes include deletion of classes
///or the schema itself, then those classes (or the schema, if it is marked
///as deleted) must not contain any instance data. If they do, an exception
///will be thrown.</summary>
/// <returns>Returns nothing</returns> 
void SuperMapApplySchemaCommand::Execute ()
{
	TRACE(_T("调用 SuperMapApplySchemaCommand::Execute() 。\n"));
    FdoSchemaElementState state;
	FdoPtr<SuperMapLpFeatureSchemaCollection> lp_schemas;
	FdoPtr<SuperMapLpFeatureSchema> schema;

	if((m_Schema == NULL) || (NULL == m_Schema->GetName()) || 0 == wcslen(m_Schema->GetName()))
	{
		throw FdoException::Create(NlsMsgGet(SUPERMAP_SCHEMA_NOT_SPECIFIED, 
			"No schema specified for the apply schema command"));
	}
	state = m_Schema->GetElementState();

	// 根据状态忽略标志不同作不同处理
	if(GetIgnoreStates())
	{
		lp_schemas = mConnection->GetLpSchemas();
		schema = lp_schemas->FindItem(m_Schema->GetName());
		if(schema == NULL)
			state = FdoSchemaElementState_Added;
		else
			state = FdoSchemaElementState_Modified;
	}

	switch(state)
	{
	case FdoSchemaElementState_Added:
		AddSchema();
		break;
	case FdoSchemaElementState_Deleted:
		DeleteSchema();
		break;
	case FdoSchemaElementState_Detached:
		break;
	case FdoSchemaElementState_Modified:
		ModifySchema();
		break;
	case FdoSchemaElementState_Unchanged:
		break;
	default:
		throw FdoException::Create(NlsMsgGet(SUPERMAP_SCHEMA_UNSUPPORTED_ELEMENT_STATE,
			"Schema element state '%l$d' is not supported.", (int)m_Schema->GetElementState()));
	}

	m_Schema->AcceptChanges();
}
///<summary>Executes the GetLockedObjects command, returning an FdoILockedObjectReader.</summary>
/// <returns>Returns FdoILockedObjectReade.r</returns> 
FdoILockedObjectReader* ArcSDEGetLockedObjectsCommand::Execute ()
{
    FdoPtr<ArcSDEConnection> connection;
    CHAR user_name[SE_MAX_OWNER_LEN];
    FdoStringP user_str;
    CHAR* user;
    LONG result;
    SE_REGINFO *registrations;
    LONG count;
    CHAR table_name[SE_QUALIFIED_TABLE_NAME];
    LONG number;
    LONG *ids;
    FdoPtr<ArcSDELockedObjectReader> ret;

    // verify the connection
    connection = static_cast<ArcSDEConnection*>(GetConnection ());
    if (connection == NULL)
        throw FdoException::Create (NlsMsgGet (ARCSDE_CONNECTION_NOT_ESTABLISHED, "Connection not established."));

    // establish an empty locked object reader
    ret = new ArcSDELockedObjectReader (connection);

    // get the user name
    if (NULL == GetLockOwner () || (0 == wcscmp (L"", GetLockOwner ())))
    {
        result = SE_connection_get_user_name (connection->GetConnection (), user_name);
        handle_sde_err<FdoCommandException> (connection->GetConnection (), result, __FILE__, __LINE__, ARCSDE_USER_UNKNOWN, "Cannot determine current user.");
        user = user_name;
    }
    else
    {
        user_str = mLockOwner.Upper();
#ifdef SDE_UNICODE
        user = (CHAR*)sde_cstwc(user_str);
#else
        sde_wide_to_multibyte (user, (FdoString*)user_str);
#endif
    }

    // process the list of registered arcsde tables, checking for locks by user (or not)
    // Read all registered arcsde tables, adding user locks on the rows to the FdoILockedObjectReader
    connection->GetArcSDERegistrationList(&registrations, &count);
    for (int i = 0; i < count; i++)
    {
        if (SE_reginfo_allow_rowlocks (registrations[i]))
        {
            result = SE_reginfo_get_table_name (registrations[i], table_name);
            handle_sde_err<FdoCommandException> (connection->GetConnection(), result, __FILE__, __LINE__, ARCSDE_REGISTRATION_INFO_ITEM, "Table registration info item '%1$ls' could not be retrieved.", L"table_name");
            result = SE_table_get_rowlocks_by_user (connection->GetConnection(), table_name, user, &number, &ids);
            handle_sde_err<FdoCommandException>(connection->GetConnection(), result, __FILE__, __LINE__, ARCSDE_GET_ROW_LOCK_LIST_FAILED, "Failed to get the row lock list.");
            for (int j = 0; j < number; j++)
                ret->AddIdentity (table_name, ids[j]);
            SE_table_free_rowlocks_list (number, ids, NULL);
        }
    }

    return (FDO_SAFE_ADDREF (ret.p));
}
/// <summary>Gets the Boolean value of the specified property. No conversion is
/// performed, thus the property must be FdoDataType_Boolean or an 
/// exception is thrown.</summary>
/// <param name="identifier">Input the property name.</param> 
/// <returns>Returns the Boolean value.</returns> 
bool SuperMapFeatureReader::GetBoolean (const FdoString* identifier)
{
	//TODO::再测试一下ORA一情况是否一样

	if(NULL == m_pRecordset || NULL == identifier)
	{
		return false;
	}

	UGC::UGString strProperName = SuperMapUtil::WcharToString(identifier).c_str();

	UGC::UGVariant var;
	m_pRecordset->GetFieldValue(strProperName, var);
	if(var.GetType() == UGC::UGVariant::Byte) // UGC类库升级后,各个引擎都放在该字段中,统一了
	{
		unsigned char ret = var.GetValue().bVal;
		TRACE(_T("调用 SuperMapFeatureReader::GetBoolean[%d] \n"), ret);
		if (ret)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	//if(var.GetType() == UGC::UGVariant::Short) // sdb/sdb+ 引擎放在SVal字段中
	//{
	//	short ret = var.GetValue().sVal;
	//	TRACE(_T("调用 SuperMapFeatureReader::GetBoolean[%d] \n"), ret);
	//	if (ret)
	//	{
	//		return true;
	//	}
	//	else
	//	{
	//		return false;
	//	}
	//}

	//if (var.GetType() == UGC::UGVariant::Integer) //SQL/SQL+ 引擎放在IVal字段中
	//{
	//	int ret = var.GetValue().iVal;
	//	TRACE(_T("调用 SuperMapFeatureReader::GetBoolean[%d] \n"), ret);
	//	if(ret)
	//	{
	//		return true;
	//	}
	//	else
	//	{
	//		return false;
	//	}
	//}
	else
	{
		throw FdoException::Create(NlsMsgGet(SUPERMAP_UNEXPECTED_DATATYPE, "The field type is not bool (%1$ls).", "GetBoolean"));
	}
}
// 确保缓存区有足够的空间来存放要添加的字符串
void SuperMapFilterStringBuffer::ReallocBuffer( size_t  Size, bool bAtEnd )
{
    size_t extraSize;

    if( bAtEnd && (m_NextBuffIndex + Size) < m_BuffSize )
	{
        return;
	}

    if( !bAtEnd && Size < m_FirstBuffIndex )
	{
        return;
	}
    extraSize = Size * 2; // 采用预分配策略,尽量避免每次都要调用该函数

    if( m_pFilterText == NULL )
    {
        m_BuffSize = ( extraSize < D_FILTER_MEM_BLOCK_ALLOC_SIZE )?D_FILTER_MEM_BLOCK_ALLOC_SIZE:extraSize;
        m_pFilterText = new char[m_BuffSize];
        if( m_pFilterText == NULL )
		{
			throw FdoException::Create (NlsMsgGet (SUPERMAP_OUT_OF_MEMORY_ERROR, "Memory Error"));
		}
        m_FirstBuffIndex = m_NextBuffIndex = m_BuffSize/2;
        m_pFilterText[m_NextBuffIndex] = '\0';
    }
    else
    {
        m_BuffSize += (( extraSize < D_FILTER_MEM_BLOCK_ALLOC_SIZE )?D_FILTER_MEM_BLOCK_ALLOC_SIZE:extraSize);
        char  *tmp = new char[m_BuffSize];
        if( tmp == NULL )
		{
            throw FdoException::Create (NlsMsgGet (SUPERMAP_OUT_OF_MEMORY_ERROR, "Memory Error"));
		}
        size_t currentSize = strlen( &m_pFilterText[m_FirstBuffIndex] );
        strncpy( &tmp[(m_BuffSize-currentSize)/2], &m_pFilterText[m_FirstBuffIndex], currentSize );
        m_FirstBuffIndex = (m_BuffSize-currentSize)/2;
        m_NextBuffIndex = m_FirstBuffIndex + currentSize;
        tmp[m_NextBuffIndex] = '\0';

        delete[] m_pFilterText;
        m_pFilterText = tmp;
    }
}
Example #15
0
void GdbiCommands::CheckDB()
{
    if( m_pRdbiContext== NULL || m_pRdbiContext->rdbi_cnct == NULL || ! m_pRdbiContext->rdbi_cnct->in_use )
            throw GdbiException::Create(NlsMsgGet(FDORDBMS_13, "Connection not established"));
    if( m_pRdbiContext->last_error_msg != NULL )
	{
		free( m_pRdbiContext->last_error_msg );
		m_pRdbiContext->last_error_msg = NULL;
	}
}
Example #16
0
/// <summary>
/// Calls on the FDO Client services to register the FdoRdbms provider.
/// Use dynamic proc address binding because there will not be a path set up yet.
/// </summary>
/// <returns>SELFREG_E_CLASS if there was an error, S_OK otherwise.</returns>
HRESULT APIENTRY DllRegisterServer (void)
{
    HRESULT ret;
    FdoRdbmsUtil  util;
    ret = SELFREG_E_CLASS; // The server was unable to complete the registration of all the object classes.
    IProviderRegistry *registry = FdoFeatureAccessManager::GetProviderRegistry();
    if (registry != NULL)
    {
        registry->RegisterProvider (RDBMS_ODBC_PROVIDER_NAME,
                                    NlsMsgGet(FDORDBMS_476, RDBMS_ODBC_PROVIDER_DEFAULT_DISPLAY_NAME),
                                    NlsMsgGet(FDORDBMS_477, RDBMS_ODBC_PROVIDER_DEFAULT_DESCRIPTION),
                                    RDBMS_ODBC_PROVIDER_VERSION,
                                    RDBMS_ODBC_FDO_VERSION,
                                    module,
                                    false);
        ret = S_OK;
    }
    return (ret);
}
void ArcSDEDataStoreReader::Validate(void)
{
    if (mDataStoreIndex < 0)
        throw FdoException::Create (NlsMsgGet1(ARCSDE_READER_NOT_READY, "Must %1$ls prior to accessing reader.", L"ReadNext"));

    FdoInt32 dataStoreCount;
    mConnProps->EnumeratePropertyValues(CONNECTIONPROPERTY_DATASTORE, dataStoreCount);

    if (mDataStoreIndex >= dataStoreCount)
        throw FdoException::Create (NlsMsgGet (ARCSDE_READER_EXHAUSTED, "Reader is exhausted."));
}
// Gets the IdentifierCollection that holds the list of property names to
// return with the result. If empty all properties of the specified class
// are returned.
FdoIdentifierCollection* FdoRdbmsSelectCommand::GetPropertyNames()
{
    if( NULL == mConnection )
         throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_13, "Connection not established"));

    if ( mIdentifiers == NULL )
        mIdentifiers = FdoIdentifierCollection::Create();

    mIdentifiers->AddRef();

    return mIdentifiers;
}
FdoIdentifierCollection* FdoRdbmsSelectCommand::GetGrouping()
{
    if( NULL == mConnection )
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_13, "Connection not established"));

    if( mGroupingCol == NULL)
        mGroupingCol = FdoIdentifierCollection::Create();

    mGroupingCol->AddRef();

    return mGroupingCol;
}
/// <summary>
/// Calls on the FDO Client services to register the SuperMap SDB/SDX provider.
/// Use dynamic proc address binding because there will not be a path set up yet.
/// </summary>
/// <returns>S_FALSE if there was an error, S_OK otherwise.</returns> 
extern "C" FDO_SUPERMAP_API HRESULT DllRegisterServer ()
{
    HRESULT ret;
	
	ret = S_FALSE;
    // Find a matching provider in the Provider Registry.
    IProviderRegistry* registry = FdoFeatureAccessManager::GetProviderRegistry();

    registry->RegisterProvider (
        SUPERMAP_PROVIDER_NAME,
        /*WTEXT(SUPERMAP_PROVIDER_DEFAULT_DISPLAY_NAME),*/
		NlsMsgGet(SUPERMAP_PROVIDER_DISPLAY_NAME, SUPERMAP_PROVIDER_DEFAULT_DISPLAY_NAME),
		/*WTEXT(SUPERMAP_PROVIDER_DEFAULT_DESCRIPTION),*/
		NlsMsgGet(SUPERMAP_PROVIDER_DESCRIPTION, SUPERMAP_PROVIDER_DEFAULT_DESCRIPTION),
        SUPERMAP_PROVIDER_VERSION,
        SUPERMAP_FDO_VERSION,
        module,
        false);
    ret = S_OK;

    return (ret);
}
/// <summary> Gets the date and time value of the specified property. No conversion is 
/// performed, thus the property must be FdoDataType_DateTime or an 
/// exception is thrown.</summary>
/// <param name="identifier">Input the property name.</param> 
/// <returns>Returns the date and time value.</returns> 
FdoDateTime SuperMapFeatureReader::GetDateTime (FdoString* identifier)
{
	if(NULL == m_pRecordset || NULL == identifier)
	{
		FdoDateTime Ftime;
		return Ftime;
	}

	UGC::UGString strProperName = SuperMapUtil::WcharToString(identifier).c_str();
	UGC::UGVariant var;
	m_pRecordset->GetFieldValue(strProperName, var);

	//if(var.GetType() == UGC::UGVariant::Double) //sdb/sdb+ 引擎将时间值放在dVal中
	//{
	//	double timeVar = var.GetValue().dVal;
	//	UGC::UGTime ugTime(timeVar);

	//	FdoDateTime Ftime((FdoInt16)ugTime.GetYear(), 
	//		(FdoInt8)ugTime.GetMonth(), 
	//		(FdoInt8)ugTime.GetDay(),
	//		(FdoInt8)ugTime.GetHour(), 
	//		(FdoInt8)ugTime.GetMinute(), 
	//		(float)ugTime.GetSecond());

	//	return Ftime;
	//}
	
	if(var.GetType() == UGC::UGVariant::Time) //UGC类库升级后,各个引擎都放在该字段中,统一了
	{
		double timeVar = var.GetValue().tVal;
		UGC::UGTime ugTime(timeVar);

		FdoDateTime Ftime((FdoInt16)ugTime.GetYear(), 
							(FdoInt8)ugTime.GetMonth(), 
							(FdoInt8)ugTime.GetDay(), 
							(FdoInt8)ugTime.GetHour(), 
							(FdoInt8)ugTime.GetMinute(), 
							(FdoInt8)ugTime.GetSecond());
		//TRACE(_T("调用 SuperMapFeatureReader::GetDateTime().年[%d].月[%d].日[%d].时[%d].分[%d].秒[%f]. \n"), Ftime.year, Ftime.month, Ftime.day, Ftime.hour, Ftime.minute, Ftime.seconds);
		return Ftime;
	}
	else
	{
		throw FdoException::Create(NlsMsgGet(SUPERMAP_UNEXPECTED_DATATYPE, "The field type is not datatime (%1$ls).", "GetDateTime"));
		//TODO::再测试是否要加
		FdoDateTime Ftime;
		return Ftime;
	}
}
/// <summary>Executes the GetLockOwners command, returning an FdoILockOwnersReader.</summary>
/// <returns>Returns the lock info reader.</returns> 
FdoILockOwnersReader* ArcSDEGetLockOwnersCommand::Execute ()
{
    FdoPtr<ArcSDEConnection> connection;
    CHAR user_name[SE_MAX_OWNER_LEN];
    LONG result;
    SE_REGINFO *registrations;
    LONG count;
    CHAR table_name[SE_QUALIFIED_TABLE_NAME];
    LONG number;
    LONG *ids;
    CHAR **users;
    FdoPtr<ArcSDELockOwnersReader> ret;

    // verify the connection
    connection = static_cast<ArcSDEConnection*>(GetConnection ());
    if (connection == NULL)
        throw FdoException::Create (NlsMsgGet (ARCSDE_CONNECTION_NOT_ESTABLISHED, "Connection not established."));

    // establish an empty lock owners reader
    ret = new ArcSDELockOwnersReader ();

    // process the list of registered arcsde tables, checking for locks by user (or not)
    // Read all registered arcsde tables, adding them into their schema:
	connection->GetArcSDERegistrationList(&registrations, &count);
    user_name[0] = '\0'; // cache to speed up processing
    for (int i = 0; i < count; i++)
    {
        if (SE_reginfo_allow_rowlocks (registrations[i]))
        {
            result = SE_reginfo_get_table_name (registrations[i], table_name);
            handle_sde_err<FdoCommandException> (connection->GetConnection (), result, __FILE__, __LINE__, ARCSDE_REGISTRATION_INFO_ITEM, "Table registration info item '%1$ls' could not be retrieved.", L"table_name");
            result = SE_table_get_rowlocks (connection->GetConnection (), table_name, &number, &ids, &users);
            handle_sde_err<FdoCommandException>(connection->GetConnection(), result, __FILE__, __LINE__, ARCSDE_GET_ROW_LOCK_LIST_FAILED, "Failed to get the row lock list.");
            for (int j = 0; j < number; j++)
            {
                if (0 != sde_strcmp (sde_pcus2wc(user_name), sde_pcus2wc(users[j])))
                {
                    wchar_t* owner;
                    sde_strcpy (sde_pus2wc(user_name), sde_pcus2wc(users[j]));
                    sde_multibyte_to_wide (owner, user_name);
                    ret->AddOwner (owner);
                }
            }
            SE_table_free_rowlocks_list (number, ids, users);
        }
    }

    return (FDO_SAFE_ADDREF (ret.p));
}
/// <summary>Gets the geometry value of the specified property as a byte array in 
/// FGF format. Because no conversion is performed, the property must be
/// of Geometric type; otherwise, an exception is thrown.</summary>
/// <param name="identifier">Input the property name.</param> 
/// <returns>Returns the byte array in FGF format.</returns> 
FdoByteArray* SuperMapFeatureReader::GetGeometry (FdoString* identifier)
{
	TRACE(_T("开始调用 SuperMapFeatureReader::GetGeometry()... \n"));
	if(NULL == m_pRecordset || NULL == identifier)
		return NULL;
	
	FdoPtr<FdoByteArray> ret; //the result for return
	SuperMapGeoToFgfGeo FgfGeo(m_pRecordset);
	ret = FgfGeo.GetGeometry();

	if(NULL == ret)
		throw FdoException::Create(NlsMsgGet(SUPERMAP_UNEXPECTED_DATATYPE, "No geometry has been queried (%1$ls).","GetGeometry"));
	
	return FDO_SAFE_ADDREF(ret.p);
}
FdoIDataStorePropertyDictionary* ArcSDEDataStoreReader::GetDataStoreProperties()
{
    FdoPtr<FdoCommonDataStorePropDictionary> dict = new FdoCommonDataStorePropDictionary(mConnection);
    char *mbPropName = NULL;
    FdoInt32 dataStoreCount;

    wide_to_multibyte(mbPropName, CONNECTIONPROPERTY_DATASTORE);
    FdoPtr<ConnectionProperty> prop = new ConnectionProperty(CONNECTIONPROPERTY_DATASTORE,
        NlsMsgGet(ARCSDE_CONNECTION_PROPERTY_DATASTORE, mbPropName),
        mConnProps->EnumeratePropertyValues(CONNECTIONPROPERTY_DATASTORE, dataStoreCount)[mDataStoreIndex],
        true, false, false, false, false, true, false, 0, NULL);
    dict->AddProperty(prop);

    return FDO_SAFE_ADDREF(dict.p);
}
/// <summary>Begins a transaction and returns an object that realizes
/// FdoITransaction.</summary>
/// <returns>Returns the transaction</returns> 
FdoITransaction* SuperMapConnection::BeginTransaction ()
{
	TRACE(_T("调用 SuperMapConnection::BeginTransaction ...\n"));
	throw FdoException::Create(NlsMsgGet(SUPERMAP_CONNECTION_TRANSACTIONS_NOT_SUPPORTED, 
		"SuperMap Provider does not support transactions."));

    //if (m_pTransaction != NULL)	// 判断是否是嵌套事务
    //    throw FdoException::Create(NlsMsgGet(SUPERMAP_NESTED_TRANSACTIONS_NOT_SUPPORTED, "Nested transactions are not supported."));
    //m_pTransaction = new SuperMapTransaction ();
    //// the connection holds a hard reference to the transaction
    //// the transaction holds a soft reference to the connection
    //m_pTransaction->AddRef ();
    //m_pTransaction->SetConnection (this);

    //return (m_pTransaction);
}
/// <summary>Sets the connection string used to open a DataStore. SetConnectionString can only be set while the
/// connection is closed.</summary>
/// <param name="value">Input the connection string</param> 
/// <returns>Returns nothing</returns> 
void SuperMapConnection::SetConnectionString (FdoString* value)
{
	TRACE(_T("调用 SuperMapConnection::SetConnectionString(%ls)。\n"), value);
	FdoConnectionState state = GetConnectionState();
	if (state == FdoConnectionState_Closed || state == FdoConnectionState_Pending)
	{
		// Update the connection string:
		m_ConnectionString = value;

		// Update the connection property dictionary:
		FdoPtr<FdoIConnectionInfo> connInfo = GetConnectionInfo();
		FdoPtr<FdoCommonConnPropDictionary> connDict = dynamic_cast<FdoCommonConnPropDictionary*>(connInfo->GetConnectionProperties());
		connDict->UpdateFromConnectionString(m_ConnectionString);
	}
	else
		throw FdoException::Create (NlsMsgGet(SUPERMAP_CONNECTION_ALREADY_OPEN, "The connection is already open."));
}
void SuperMapTransaction::SetConnection (SuperMapConnection* pConnection)
{
	// 事务开始
	m_pConnection = pConnection;
	if (NULL != m_pConnection)
	{
		TRACE(_T("调用 SuperMapTransaction::SetConnection [开始事务]...\n"));
		UGC::UGDataSource* pDataSource = m_pConnection->GetDataSource();
		if(pDataSource->IsTransacted())	// 判断数据源是否支持短事务操作
		{
			if(!pDataSource->BeginTrans())
			{
				throw FdoException::Create(NlsMsgGet(SUPERMAP_TRANSACTIONS_NOT_START, 
										"Failed to start transaction."));
			}
		}
	}
}
bool FdoRdbmsSQLDataReader::ReadNext()
{
    if( mQueryResult == NULL )
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_43, "Query ended"));

    mHasMoreRows = false;
    mGeomIdx = -1;

    if ( ! mQueryResult->ReadNext() )
    {
        Close();
        return false;
    }

 	for (int i=0; i < mColCount; i++)
		mSprops[i].valid = 0;

    return (mHasMoreRows = true);
}
/// <summary>Gets the 64-bit integer value of the specified property. No conversion is
/// performed, thus the property must be FdoDataType_Int64 or an exception
/// is thrown.</summary>
/// <param name="identifier">Input the property name.</param> 
/// <returns>Returns the FdoInt64 value.</returns> 
FdoInt64 SuperMapFeatureReader::GetInt64 (FdoString* identifier)
{
	if(NULL == m_pRecordset || NULL == identifier)
	{
		return 0;
	}

	UGC::UGString strProperName = SuperMapUtil::WcharToString(identifier).c_str();
	UGC::UGVariant var;
	m_pRecordset->GetFieldValue(strProperName, var);
	if(var.GetType() == UGC::UGVariant::Long)
	{
		FdoInt64 ret = (FdoInt64)var.GetValue().lVal;
		return ret;
	}
	else
	{
		throw FdoException::Create(NlsMsgGet(SUPERMAP_UNEXPECTED_DATATYPE, "The field type is not long (%1$ls).", "GetInt64"));
	}
}
void ArcSDEDestroySpatialContext::Execute()
{
    // Validate name:
    if (m_wcsName==L"")
        throw FdoCommandException::Create(NlsMsgGet(ARCSDE_SPATIALCONTEXT_NAME_NOT_SPECIFIED, "Spatial context name not specified."));

    // Convert name to SRID:
    LONG lSRID = ArcSDESpatialContextUtility::SpatialContextNameToSRID(mConnection, m_wcsName);

    // Perform the delete:
    LONG lResult = SE_spatialref_delete(mConnection->GetConnection(), lSRID);
    handle_sde_err<FdoCommandException>(mConnection->GetConnection(), lResult, __FILE__, __LINE__, ARCSDE_SPATIALCONTEXT_DELETE_FAILED, "Failed to delete spatial context '%1$ls'.", (const wchar_t*)m_wcsName);

    // Clear spatial context cache since the list has now changed:
    mConnection->DecacheSpatialContexts();

    // If this was the active spatial context, reset the active spatial context:
    if ((mConnection->GetActiveSpatialContext() != NULL) && (0==wcscmp(m_wcsName, mConnection->GetActiveSpatialContext())))
        mConnection->SetActiveSpatialContextToDefault();
}