Windows文件检索之——查询条件

这一节讲如何实现查询条件。

我们把查询条件封装成了一个类,SdkQueryCondition,它的本质是对ICondition这个COM接口进行的封装。

1.SdkQueryCondition接口

下面列出SdkQueryCondition类的公共接口。

HRESULT GetCondition(ICondition **ppc);
HRESULT SetCondition(LPCWSTR *ppszQuerys, UINT32 uCount);
HRESULT SetCondition(INT32 queryKind);
HRESULT ClearCondtions();
第一个函数GetCondition就是得到ICondition的接口,这个方法是在SdkFileSearcher这个类里面调用的(请参考第一部分)。
第二个函数就是设置一个Condition,这个条件可能是后缀数组,如*.txt, *.jpg等。
第三个函数是一个重载,也是用于设置Condition,用户可以设置一个系统定义的文件类型,如music,video,picture等。
第四个函数就是用来清除上一次设置的查询条件。

2.SdkQueryCondition实现

SdkQueryCondition.h文件 

#ifdef __cplusplus
#ifndef _QUERYCONDITION_H_
#define _QUERYCONDITION_H_

#include "SdkCommon.h"

/*!
* @brief The search condition kind
*/
typedef enum _QUERYCONDITIONKIND
{
    QUERY_KIND_NONE         = 0x00000000,
    QUERY_KIND_MUSIC        = 0x00000001,
    QUERY_KIND_VIDEO        = 0x00000002,
    QUERY_KIND_PICTURE      = 0x00000004,
    QUERY_KIND_DOCUMENT     = 0x00000008,
    QUERY_KIND_LINK         = 0x00000010,
    QUERY_KIND_RECENT       = 0x00000020,

} QUERYCONDITIONKIND;

/*!
* @brief QueryCondition class to manage searching condition.
*/
class CLASS_DECLSPEC SdkQueryCondition
{
public:

    SdkQueryCondition();
    ~SdkQueryCondition();

    HRESULT GetCondition(ICondition **ppc);
    HRESULT SetCondition(LPCWSTR *ppszQuerys, UINT32 uCount);
    HRESULT SetCondition(INT32 queryKind);
    HRESULT ClearCondtions();

private:

    HRESULT CreateQueryParser();
    HRESULT ParseStructuredQuery(QUERYCONDITIONKIND kind, 
        OUT ICondition **ppc);
    HRESULT ParseStructuredQuery(PCWSTR pszString, 
        OUT ICondition **ppc);
    HRESULT GetQueryKindList(OUT vector<QUERYCONDITIONKIND> &vctKinds);

private:

    // The query kind value.
    INT32                m_nQueryKind;   
    // The count of query condition array.       
    UINT32               m_uQueryCount;   
    // The query condition array.      
    PCWSTR              *m_pszQuerys;   
    // The query parser.        
    IQueryParser        *m_pQueryParser;        
};

#endif // _QUERYCONDITION_H_
#endif // __cplusplus

SdkQueryCondition.cpp文件

#include "SdkQueryCondition.h"

typedef struct _QUERYPARSEROPTIONS
{
    PCWSTR pszPropertyName;
    PCWSTR pszSemanticType;

} QUERYPARSEROPTIONS, *LPQUERYPARSEROPTIONS;

const QUERYPARSEROPTIONS g_rgGenericProperties[] =
{
    { L"System.Generic.String",          L"System.StructuredQueryType.String" },
    { L"System.Generic.Integer",         L"System.StructuredQueryType.Integer" },
    { L"System.Generic.DateTime",        L"System.StructuredQueryType.DateTime" },
    { L"System.Generic.Boolean",         L"System.StructuredQueryType.Boolean" },
    { L"System.Generic.FloatingPoint",   L"System.StructuredQueryType.FloatingPoint" }
};

//

SdkQueryCondition::SdkQueryCondition() : m_pQueryParser(NULL),
                                   m_pszQuerys(NULL),
                                   m_nQueryKind(0),
                                   m_uQueryCount(0)
{
}

//

SdkQueryCondition::~SdkQueryCondition()
{
    SAFE_RELEASE(m_pQueryParser);
    ClearCondtions();
}

//

HRESULT SdkQueryCondition::GetCondition(ICondition **ppc)
{
    if (NULL == ppc)
    {
        return E_INVALIDARG;
    }

    *ppc = NULL;
    IConditionFactory2 *pConditionFactory = NULL;
    HRESULT hr = CoCreateInstance(CLSID_ConditionFactory, NULL, 
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConditionFactory));
    if (FAILED(hr))
    {
        return hr;
    }

    vector<ICondition*> vctConditions;
    vector<QUERYCONDITIONKIND> vctKinds;
    hr = CreateQueryParser();
    hr = GetQueryKindList(vctKinds);

    for (UINT32 i = 0; i < m_uQueryCount; ++i)
    {
        ICondition *pCondition = NULL;
        hr = ParseStructuredQuery(m_pszQuerys[i], &pCondition);
        if (SUCCEEDED(hr))
        {
            vctConditions.push_back(pCondition);
        }
    }

    for each (QUERYCONDITIONKIND kind in vctKinds)
    {
        ICondition *pCondition = NULL;
        hr = ParseStructuredQuery(kind, &pCondition);
        if (SUCCEEDED(hr))
        {
            vctConditions.push_back(pCondition);
        }
    }

    int conditionCount = vctConditions.size();
    hr = (conditionCount > 0) ? S_OK : E_FAIL;

    if (conditionCount > 0)
    {
        ICondition **pszConditions = new ICondition*[conditionCount];
        for (int i = 0; i < conditionCount; ++i)
        {
            pszConditions[i] = vctConditions[i];
        }

        hr = pConditionFactory->CreateCompoundFromArray(CT_OR_CONDITION,
            pszConditions, conditionCount,
            CONDITION_CREATION_DEFAULT, IID_PPV_ARGS(ppc));

        // Release the memory.
        for (int i = 0; i < conditionCount; ++i)
        {
            SAFE_RELEASE(pszConditions[i]);
        }

        SAFE_DELETE_ARRAY(pszConditions);
    }

    SAFE_RELEASE(pConditionFactory);

    return hr;
}

//

HRESULT SdkQueryCondition::SetCondition(LPCWSTR *ppszQuerys, UINT32 uCount)
{
    if ( (NULL == ppszQuerys) || (0 == uCount) )
    {
        return E_INVALIDARG;
    }

    ClearCondtions();
    m_uQueryCount = uCount;
    m_pszQuerys = new PCWSTR[uCount];
    memset(m_pszQuerys, 0, uCount * sizeof(PCWSTR));

    for (UINT32 i = 0; i < uCount; ++i)
    {
        int length  = wcslen(ppszQuerys[i]);
        int ccbDest = sizeof(WCHAR) * (length + 1);
        int ccbSrc  = sizeof(WCHAR) * length;

        WCHAR *pDest = new WCHAR[length + 1];
        memset(pDest, 0, ccbDest);
        memcpy_s(pDest, ccbDest, ppszQuerys[i], ccbSrc);
        m_pszQuerys[i] = pDest;
    }

    return S_OK;
}

//

HRESULT SdkQueryCondition::SetCondition(INT32 queryKind)
{
    m_nQueryKind = queryKind;

    return S_OK;
}

//

HRESULT SdkQueryCondition::ClearCondtions()
{
    if (NULL != m_pszQuerys)
    {
        for (UINT32 i = 0; i < m_uQueryCount; ++i)
        {
            SAFE_DELETE_ARRAY(m_pszQuerys[i]);
        }

        SAFE_DELETE_ARRAY(m_pszQuerys);
    }

    m_uQueryCount = 0;

    return S_OK;
}

//

HRESULT SdkQueryCondition::CreateQueryParser()
{
    SAFE_RELEASE(m_pQueryParser);
    IQueryParserManager *pQueryParserManager = NULL;

    HRESULT hr = CoCreateInstance(CLSID_QueryParserManager, NULL, 
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pQueryParserManager));
    if (SUCCEEDED(hr))
    {
        IQueryParser *pQueryParser = NULL;
        hr = pQueryParserManager->CreateLoadedParser(L"SystemIndex", 
            LOCALE_USER_DEFAULT, IID_PPV_ARGS(&pQueryParser));
        if (SUCCEEDED(hr))
        {
            hr = pQueryParserManager->InitializeOptions(FALSE, TRUE, pQueryParser);
            for (int i = 0; i < ARRAYSIZE(g_rgGenericProperties) && SUCCEEDED(hr); ++i)
            {
                PCWSTR pszPropertyName = g_rgGenericProperties[i].pszPropertyName;
                PCWSTR pszSemanticType = g_rgGenericProperties[i].pszSemanticType;

                PROPVARIANT propVar;
                hr = InitPropVariantFromString(pszPropertyName, &propVar);
                hr = pQueryParser->SetMultiOption(SQMO_DEFAULT_PROPERTY, 
                    pszSemanticType, &propVar);
                PropVariantClear(&propVar);
            }

            if (SUCCEEDED(hr))
            {
                pQueryParser->QueryInterface(IID_PPV_ARGS(&m_pQueryParser));
            }
        }

        SAFE_RELEASE(pQueryParser);
    }

    SAFE_RELEASE(pQueryParserManager);

    return hr;
}

//

HRESULT SdkQueryCondition::ParseStructuredQuery(QUERYCONDITIONKIND kind, 
    OUT ICondition **ppc)
{
    LPCWSTR strKind = NULL;

    switch (kind)
    {
    case QUERY_KIND_MUSIC:
        strKind = KIND_MUSIC;
        break;

    case QUERY_KIND_VIDEO:
        strKind = KIND_VIDEO;
        break;

    case QUERY_KIND_PICTURE:
        strKind = KIND_PICTURE;
        break;

    case QUERY_KIND_DOCUMENT:
        strKind = KIND_DOCUMENT;
        break;

    case QUERY_KIND_LINK:
        strKind = KIND_LINK;
        break;
    }

    if (NULL == strKind)
    {
        return E_INVALIDARG;
    }

    IConditionFactory2 *pConditionFactory = NULL;
    HRESULT hr = CoCreateInstance(CLSID_ConditionFactory, NULL, 
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConditionFactory));
    if (SUCCEEDED(hr))
    {
        hr = pConditionFactory->CreateStringLeaf(PKEY_Kind, 
            COP_EQUAL, strKind, 
            NULL, CONDITION_CREATION_DEFAULT, IID_PPV_ARGS(ppc));
    }

    SAFE_RELEASE(pConditionFactory);

    return hr;
}

//

HRESULT SdkQueryCondition::ParseStructuredQuery(PCWSTR pszString, 
    OUT ICondition **ppc)
{
    if ( (NULL == ppc) || (NULL == m_pQueryParser) )
    {
        return E_INVALIDARG;
    }

    IQuerySolution *pQuerySolution = NULL;
    HRESULT hr = m_pQueryParser->Parse(pszString, NULL, &pQuerySolution);
    if (SUCCEEDED(hr))
    {
        ICondition *pCondition = NULL;
        hr = pQuerySolution->GetQuery(&pCondition, NULL);
        if (SUCCEEDED(hr))
        {
            SYSTEMTIME sysTime;
            GetLocalTime(&sysTime);
            hr = pQuerySolution->Resolve(pCondition, 
                SQRO_DONT_SPLIT_WORDS, &sysTime, ppc);
        }
        SAFE_RELEASE(pCondition);
    }

    SAFE_RELEASE(pQuerySolution);

    return hr;
}

//

HRESULT SdkQueryCondition::GetQueryKindList(OUT vector<QUERYCONDITIONKIND> &vctKinds)
{
    FILTER_BITVALUE(m_nQueryKind, QUERY_KIND_MUSIC,     vctKinds);
    FILTER_BITVALUE(m_nQueryKind, QUERY_KIND_VIDEO,     vctKinds);
    FILTER_BITVALUE(m_nQueryKind, QUERY_KIND_PICTURE,   vctKinds);
    FILTER_BITVALUE(m_nQueryKind, QUERY_KIND_DOCUMENT,  vctKinds);
    FILTER_BITVALUE(m_nQueryKind, QUERY_KIND_LINK,      vctKinds);

    return S_OK;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值