IViewFilter

IViewFilter enables consumers to restrict the contents of a rowset to rows matching a set of conditions.

When to Implement

Providers that can define a subset of rows based on a consumer-defined set of conditions expose IViewFilter. A provider may restrict functionality to filters based on existing indexes, or filters may require a specific sort order also to be applied.

When to Call

Consumers needing a subset of rows can call IViewFilter::SetFilter to apply a filter condition to a view. Rowsets or chapters opening using this view expose only those rows that match the criteria. Each view can have only a single filter applied, but a view containing a filter can be applied to an existing filtered chapter to further filter its contents.

Filter criteria are expressed as an array of rows and columns, with an associated set of comparison operators.

Within a row of the criteria array, each column corresponds to a column in the table. The mapping of the columns in the criteria array to the columns in the table is done through an accessor passed into SetFilter or GetFilter. The same column from the table may appear once, more than once, or not at all in the criteria array. Each column in the criteria array has a corresponding comparison operation that defines how the value passed in the criteria array is to be compared to the value of the corresponding column in the rowset. Each column of the criteria array is joined in a logical AND with the other columns in that row of the criteria array.

The criteria array can contain multiple rows. In this case, the array of comparison operations is a two-dimensional array stored in row-major format, such that the comparison operators for each of the columns of the first row in the criteria array are followed by the comparison operators for each column of the second row in the criteria array, and so forth. Multiple rows in the criteria array are joined together in a logical OR.

For example, assume the following rowset:

Name Children State
Joe 0 WA
Jane 2 WA
Fred 3 OR
Judy 1 OR
Jane 2 ID

The following table shows the results for various combinations of accessor bindings, criteria array, and comparison operators.

Accessor Criteria Array Comparison Ops Result
rgBindings[0].iOrdinal = 3 {DBCOMPAREOPS_EQ} {"WA"} "Joe"0 "WA"

"Jane"2 "WA"

rgBindings[0].iOrdinal=3 {DBCOMPAREOPS_EQ, DBCOMPAREOPS_EQ} {"WA","ID"} "Joe"0 "WA"

"Jane"2 "WA"

"Jane"2 "ID"

rgBindings[0].iOrdinal=3

rgBindings[1].iOrdinal=2

{DBCOMPAREOPS_EQ, DBCOMPAREOPS_GT} {"OR",1} "Fred"3 "OR"
rgBindings[0].iOrdinal=3

rgBindings[1].iOrdinal=2

{DBCOMPAREOPS_EQ, DBCOMPAREOPS_IGNORE, DBCOMPAREOPS_IGNORE, DBCOMPAREOPS_GT} {"OR",NULL, NULL,1} "Jane"2 "WA"

"Fred"3 "OR"

"Judy"1 "OR"

"Jane"2 "ID"



The following code example shows defining a filter for which the individual is from Oregon or has more than one child:

DBBINDING    rgBindings[2];
IAccessor     *pIAccessor;
HACCESSOR    hAccessor;
DBCOMPAREOP    rgCompareOps[] = { DBCOMPAREOP_EQ, DBCOMPAREOP_IGNORE,
                          DBCOMPAREOP_IGNORE, DBCOMPAREOP_GT };

typedef struct FILTER_CRITERIA {
   TCHAR    rcState[4];
   ULONG    ulStateStatus;
   ULONG    ulStateLength;
   ULONG    cChildren;
   ULONG    ulChildrenStatus;
} WHERE_CLAUSE;

WHERE_CLAUSE rgCriteriaData[] =
{
   _T("OR"), DBSTATUS_S_OK,   2 * sizeof(TCHAR), NULL, DBSTATUS_S_ISNULL,
   NULL,   DBSTATUS_S_ISNULL, 0,       1,  DBSTATUS_S_OK
};

//initialize common binding values
for (cCol = 0; cCol < 2; cCol++)
{
   rgBindings[cCol].pTypeInfo   = NULL;
   rgBindings[cCol].pObject   = NULL;
   rgBindings[cCol].pBindExp   = NULL;
   rgBindings[cCol].dwMemOwner   = DBMEMOWNER_CLIENTOWNED;
   rgBindings[cCol].eParamIO   = DBPARAMIO_NOTPARAM;
   rgBindings[cCol].dwFlags   = 0;
   rgBindings[cCol].bPrecision   = 0;
   rgBindings[cCol].bScale      = 0;
}

//initial bindings for the "State" column
   rgBindings[0].dwPart   = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
   rgBindings[0].iOrdinal   = 3;
   rgBindings[0].wType      = DBTYPE_STR;
   rgBindings[0].obValue   = offsetof(WHERE_CLAUSE, rcState);
   rgBindings[0].obStatus   = offsetof(WHERE_CLAUSE, ulStateStatus);
   rgBindings[0].obLength   = offsetof(WHERE_CLAUSE, ulStateLength);
   rgBindings[0].cbMaxLen   = sizeof(WHERE_CLAUSE.rcState);

//initial bindings for the "Children" column
   rgBindings[1].dwPart   =
   rgBindings[1].iOrdinal   = 2
   rgBindings[1].wType      = DBTYPE_I4;
   rgBindings[1].obValue   = offsetof(WHERE_CLAUSE, cChildren);
   rgBindings[1].obStatus   = offsetof(WHERE_CLAUSE, ulChildrenStatus);
   rgBindings[0].obLength   = 0;
   rgBindings[1].cbMaxLen   = sizeof(WHERE_CLAUSE.cChildren);

pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 2, rgBindings, sizeof(WHERE_CLAUSE), &hAccessor, NULL);

//set filter condition
pIViewFilter->SetFilter(hAccessor, 2, rgCompareOps, rgCriteriaData);
Method Description
GetFilter Returns the filter condition associated with a view.
GetFilterBindings Returns the bindings used to describe the filter conditions associated with a view.
SetFilter Sets a filter condition on a view.