Skip to content

Commit ab48002

Browse files
committed
feat: add support for explicit chain filters
1 parent da373b5 commit ab48002

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/filter.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,48 @@ export class Filter {
609609
});
610610
}
611611

612+
/**
613+
* This filter applies a series of filters, in order, to each output row. A chain filter is like using a logical AND.
614+
*
615+
* @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.
616+
*
617+
* @example
618+
* ```
619+
* //-
620+
* // In the following example, we're creating a filter that will retrieve
621+
* // results for entries that were created between December 17th, 2015
622+
* // and March 22nd, 2016 and entries that have data for `follows:tjefferson`.
623+
* //-
624+
* const filter = [
625+
* {
626+
* chain: [
627+
* [
628+
* {
629+
* time: {
630+
* start: new Date('December 17, 2015'),
631+
* end: new Date('March 22, 2016')
632+
* }
633+
* }
634+
* ],
635+
* [
636+
* {
637+
* family: 'follows'
638+
* },
639+
* {
640+
* column: 'tjefferson'
641+
* }
642+
* ]
643+
* ]
644+
* }
645+
* ];
646+
* ```
647+
*/
648+
chain(filters: RawFilter[]): void {
649+
this.set('chain', {
650+
filters: filters.map(Filter.parse),
651+
});
652+
}
653+
612654
/**
613655
* Applies the given label to all cells in the output row. This allows
614656
* the client to determine which results were produced from which part of

test/filter.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,28 @@ describe('Bigtable/Filter', () => {
376376
});
377377
});
378378

379+
describe('chain', () => {
380+
it('should create a chain filter', done => {
381+
const fakeFilters = [{}, {}, {}];
382+
383+
const spy = sandbox.stub(Filter, 'parse').returnsArg(0);
384+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
385+
filter.set = (filterName, value: any) => {
386+
assert.strictEqual(filterName, 'chain');
387+
assert.strictEqual(value.filters[0], fakeFilters[0]);
388+
assert.strictEqual(value.filters[1], fakeFilters[1]);
389+
assert.strictEqual(value.filters[2], fakeFilters[2]);
390+
assert.strictEqual(spy.getCall(0).args[0], fakeFilters[0]);
391+
assert.strictEqual(spy.getCall(1).args[0], fakeFilters[1]);
392+
assert.strictEqual(spy.getCall(2).args[0], fakeFilters[2]);
393+
spy.restore();
394+
done();
395+
};
396+
397+
filter.chain(fakeFilters);
398+
});
399+
});
400+
379401
describe('label', () => {
380402
it('should apply the label transformer', done => {
381403
const label = 'label';

0 commit comments

Comments
 (0)