Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,48 @@ export class Filter {
});
}

/**
* This filter applies a series of filters, in order, to each output row. A chain filter is like using a logical AND.
*
* @param {object} filters Each filter in the chain sees only the output of the previous filter. For example, if you chain two filters, and the first filter removes half of the cells from the output row, the second filter does not have access to the cells that were removed.
*
* @example
* ```
* //-
* // In the following example, we're creating a filter that will retrieve
* // results for entries that were created between December 17th, 2015
* // and March 22nd, 2016 and entries that have data for `follows:tjefferson`.
* //-
* const filter = [
* {
* chain: [
* [
* {
* time: {
* start: new Date('December 17, 2015'),
* end: new Date('March 22, 2016')
* }
* }
* ],
* [
* {
* family: 'follows'
* },
* {
* column: 'tjefferson'
* }
* ]
* ]
* }
* ];
* ```
*/
chain(filters: RawFilter[]): void {
this.set('chain', {
filters: filters.map(Filter.parse),
});
}

/**
* Applies the given label to all cells in the output row. This allows
* the client to determine which results were produced from which part of
Expand Down
22 changes: 22 additions & 0 deletions test/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,28 @@ describe('Bigtable/Filter', () => {
});
});

describe('chain', () => {
it('should create a chain filter', done => {
const fakeFilters = [{}, {}, {}];

const spy = sandbox.stub(Filter, 'parse').returnsArg(0);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
filter.set = (filterName, value: any) => {
assert.strictEqual(filterName, 'chain');
assert.strictEqual(value.filters[0], fakeFilters[0]);
assert.strictEqual(value.filters[1], fakeFilters[1]);
assert.strictEqual(value.filters[2], fakeFilters[2]);
assert.strictEqual(spy.getCall(0).args[0], fakeFilters[0]);
assert.strictEqual(spy.getCall(1).args[0], fakeFilters[1]);
assert.strictEqual(spy.getCall(2).args[0], fakeFilters[2]);
spy.restore();
done();
};

filter.chain(fakeFilters);
});
});

describe('label', () => {
it('should apply the label transformer', done => {
const label = 'label';
Expand Down