-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: unifying node and browser code (#115)
* unifiying node and browser code * bumped package versions * formatting fix * added test case for get-filter-params-sql * added test cases * reverted uneeded changes
- Loading branch information
1 parent
61708d0
commit 2ad2540
Showing
10 changed files
with
307 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
meerkat-core/src/get-filter-params-sql/get-filter-params-sql.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import { Database } from 'duckdb'; | ||
import { TableSchema } from '../types/cube-types'; | ||
import { getFilterParamsSQL } from './get-filter-params-sql'; | ||
|
||
const getQueryOutput = async (sql: string) => { | ||
const db = new Database(':memory:') | ||
return new Promise((resolve, reject) => { | ||
db.all(sql, (err, res) => { | ||
if (err) { | ||
reject(err); | ||
} | ||
resolve(res); | ||
}); | ||
}); | ||
} | ||
|
||
const TABLE_SCHEMA: TableSchema = { | ||
name: 'orders', | ||
sql: "select * from orders WHERE ${FILTER_PARAMS.orders.status.filter('status')}", | ||
measures: [], | ||
dimensions: [ | ||
{ name: 'id', sql: 'id', type: 'number' }, | ||
{ name: 'date', sql: 'date', type: 'string' }, | ||
{ name: 'status', sql: 'status', type: 'string' }, | ||
{ name: 'amount', sql: 'amount', type: 'number' } | ||
] | ||
} | ||
describe('getFilterParamsSQL', () => { | ||
it('should find filter params when there are filters of base filter type', async () => { | ||
const result = await getFilterParamsSQL({ | ||
filterType: 'BASE_FILTER', | ||
query: { | ||
measures: [ '*' ], | ||
filters: [ | ||
{ | ||
and: [ | ||
{ member: 'orders.amount', operator: 'notSet' }, | ||
{ member: 'orders.status', operator: 'set' } | ||
] | ||
} | ||
], | ||
dimensions: [] | ||
}, | ||
tableSchema: TABLE_SCHEMA, | ||
getQueryOutput, | ||
}); | ||
expect(result).toEqual([ | ||
{ | ||
"matchKey": "${FILTER_PARAMS.orders.status.filter('status')}", | ||
"memberKey": "orders.status", | ||
"sql": "SELECT * FROM REPLACE_BASE_TABLE WHERE ((orders.status IS NOT NULL))", | ||
}, | ||
]); | ||
}); | ||
it('should not find filter params when there are no filters of base filter type', async () => { | ||
const result = await getFilterParamsSQL({ | ||
filterType: 'BASE_FILTER', | ||
query: { | ||
measures: [ '*' ], | ||
filters: [], | ||
dimensions: [] | ||
}, | ||
tableSchema: TABLE_SCHEMA, | ||
getQueryOutput, | ||
}); | ||
expect(result).toEqual([]); | ||
}); | ||
it('should find filter params when there are filters of projection filter type', async () => { | ||
const result = await getFilterParamsSQL({ | ||
filterType: 'PROJECTION_FILTER', | ||
query: { | ||
measures: [ '*' ], | ||
filters: [ | ||
{ | ||
and: [ | ||
{ member: 'orders.amount', operator: 'notSet' }, | ||
{ member: 'orders.status', operator: 'set' } | ||
] | ||
} | ||
], | ||
dimensions: [] | ||
}, | ||
tableSchema: TABLE_SCHEMA, | ||
getQueryOutput, | ||
}); | ||
expect(result).toEqual([ | ||
{ | ||
"matchKey": "${FILTER_PARAMS.orders.status.filter('status')}", | ||
"memberKey": "orders.status", | ||
"sql": "SELECT * FROM REPLACE_BASE_TABLE WHERE ((orders__status IS NOT NULL))", | ||
}, | ||
]); | ||
}); | ||
it('should not find filter params when there are no filters', async () => { | ||
const result = await getFilterParamsSQL({ | ||
filterType: 'PROJECTION_FILTER', | ||
query: { | ||
measures: [ '*' ], | ||
filters: [], | ||
dimensions: [] | ||
}, | ||
tableSchema: TABLE_SCHEMA, | ||
getQueryOutput, | ||
}); | ||
expect(result).toEqual([]); | ||
}); | ||
it('should find filter params when there are filters of no defined type', async () => { | ||
const result = await getFilterParamsSQL({ | ||
query: { | ||
measures: [ '*' ], | ||
filters: [ | ||
{ | ||
and: [ | ||
{ member: 'orders.amount', operator: 'notSet' }, | ||
{ member: 'orders.status', operator: 'set' } | ||
] | ||
} | ||
], | ||
dimensions: [] | ||
}, | ||
tableSchema: TABLE_SCHEMA, | ||
getQueryOutput, | ||
}); | ||
expect(result).toEqual([ | ||
{ | ||
"matchKey": "${FILTER_PARAMS.orders.status.filter('status')}", | ||
"memberKey": "orders.status", | ||
"sql": "SELECT * FROM REPLACE_BASE_TABLE WHERE ((orders__status IS NOT NULL))", | ||
}, | ||
]); | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
meerkat-core/src/get-filter-params-sql/get-filter-params-sql.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { astDeserializerQuery, deserializeQuery } from "../ast-deserializer/ast-deserializer"; | ||
import { getFilterParamsAST } from "../filter-params/filter-params-ast"; | ||
import { FilterType, Query, TableSchema } from "../types/cube-types"; | ||
|
||
export const getFilterParamsSQL = async ({ | ||
query, | ||
tableSchema, | ||
filterType, | ||
getQueryOutput | ||
}: { | ||
query: Query; | ||
tableSchema: TableSchema; | ||
filterType?: FilterType; | ||
getQueryOutput: (query: string) => Promise<any>; | ||
}) => { | ||
const filterParamsAST = getFilterParamsAST( | ||
query, | ||
tableSchema, | ||
filterType | ||
); | ||
const filterParamsSQL = []; | ||
for (const filterParamAST of filterParamsAST) { | ||
if (!filterParamAST.ast) { | ||
continue; | ||
} | ||
|
||
const queryOutput = await getQueryOutput(astDeserializerQuery(filterParamAST.ast)) | ||
const sql = deserializeQuery(queryOutput); | ||
|
||
filterParamsSQL.push({ | ||
memberKey: filterParamAST.memberKey, | ||
sql: sql, | ||
matchKey: filterParamAST.matchKey, | ||
}); | ||
} | ||
return filterParamsSQL; | ||
}; |
69 changes: 69 additions & 0 deletions
69
meerkat-core/src/get-final-base-sql/get-final-base-sql.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Database } from 'duckdb'; | ||
import { TableSchema } from '../types/cube-types'; | ||
import { getFinalBaseSQL } from './get-final-base-sql'; | ||
|
||
const getQueryOutput = async (sql: string) => { | ||
const db = new Database(':memory:') | ||
return new Promise((resolve, reject) => { | ||
db.all(sql, (err, res) => { | ||
if (err) { | ||
reject(err); | ||
} | ||
resolve(res); | ||
}); | ||
}); | ||
} | ||
|
||
const TABLE_SCHEMA: TableSchema = { | ||
name: 'orders', | ||
sql: "select * from orders WHERE ${FILTER_PARAMS.orders.status.filter('status')}", | ||
measures: [ | ||
{ name: 'count', sql: 'COUNT(*)', type: 'number' } | ||
], | ||
dimensions: [ | ||
{ name: 'id', sql: 'id', type: 'number' }, | ||
{ name: 'date', sql: 'date', type: 'string' }, | ||
{ name: 'status', sql: 'status', type: 'string' }, | ||
{ name: 'amount', sql: 'amount', type: 'number' } | ||
] | ||
} | ||
describe('get final base sql', () => { | ||
it('should not return measures in the projected base sql when filter param passed', async () => { | ||
const result = await getFinalBaseSQL({ | ||
query: { | ||
measures: ['orders.count'], | ||
filters: [ | ||
{ | ||
and: [ | ||
{ member: 'orders.amount', operator: 'notSet' }, | ||
{ member: 'orders.status', operator: 'set' } | ||
] | ||
} | ||
], | ||
dimensions: ['orders.status'] | ||
}, | ||
tableSchema: TABLE_SCHEMA, | ||
getQueryOutput, | ||
}); | ||
expect(result).toEqual('SELECT *, amount AS orders__amount, status AS orders__status FROM (select * from orders WHERE ((orders.status IS NOT NULL))) AS orders'); | ||
}); | ||
it('should not return measures in the projected base sql when filter param not passed', async () => { | ||
const result = await getFinalBaseSQL({ | ||
query: { | ||
measures: ['orders.count'], | ||
filters: [ | ||
{ | ||
and: [ | ||
{ member: 'orders.amount', operator: 'notSet' }, | ||
] | ||
} | ||
], | ||
dimensions: ['orders.status'] | ||
}, | ||
tableSchema: TABLE_SCHEMA, | ||
getQueryOutput, | ||
}); | ||
expect(result).toEqual('SELECT *, amount AS orders__amount, status AS orders__status FROM (select * from orders WHERE TRUE) AS orders'); | ||
}); | ||
}); | ||
|
Oops, something went wrong.