mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-02 18:23:59 +00:00
fixed evaluated filters
This commit is contained in:
@@ -163,6 +163,7 @@ class JsonLinesDatastore {
|
|||||||
const res = [];
|
const res = [];
|
||||||
await lock.acquire('reader', async () => {
|
await lock.acquire('reader', async () => {
|
||||||
await this._ensureReader(offset, filter);
|
await this._ensureReader(offset, filter);
|
||||||
|
// console.log(JSON.stringify(this.currentFilter, undefined, 2));
|
||||||
for (let i = 0; i < limit; i += 1) {
|
for (let i = 0; i < limit; i += 1) {
|
||||||
const line = await this._readLine(true);
|
const line = await this._readLine(true);
|
||||||
if (line == null) break;
|
if (line == null) break;
|
||||||
|
|||||||
@@ -652,7 +652,8 @@ export abstract class GridDisplay {
|
|||||||
for (const name in filters) {
|
for (const name in filters) {
|
||||||
const column = this.isDynamicStructure ? null : this.columns.find(x => x.columnName == name);
|
const column = this.isDynamicStructure ? null : this.columns.find(x => x.columnName == name);
|
||||||
if (!this.isDynamicStructure && !column) continue;
|
if (!this.isDynamicStructure && !column) continue;
|
||||||
const filterType = this.isDynamicStructure ? this.filterTypeOverride ?? 'mongo' : getFilterType(column.dataType);
|
const filterType =
|
||||||
|
this.filterTypeOverride ?? (this.isDynamicStructure ? 'mongo' : getFilterType(column.dataType));
|
||||||
try {
|
try {
|
||||||
const condition = parseFilter(filters[name], filterType);
|
const condition = parseFilter(filters[name], filterType);
|
||||||
const replaced = _.cloneDeepWith(condition, (expr: Expression) => {
|
const replaced = _.cloneDeepWith(condition, (expr: Expression) => {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export class JslGridDisplay extends GridDisplay {
|
|||||||
this.filterable = true;
|
this.filterable = true;
|
||||||
this.supportsReload = supportsReload;
|
this.supportsReload = supportsReload;
|
||||||
this.isDynamicStructure = isDynamicStructure;
|
this.isDynamicStructure = isDynamicStructure;
|
||||||
if (isDynamicStructure) this.filterTypeOverride = 'string';
|
this.filterTypeOverride = 'eval';
|
||||||
|
|
||||||
if (structure?.columns) {
|
if (structure?.columns) {
|
||||||
this.columns = _.uniqBy(
|
this.columns = _.uniqBy(
|
||||||
|
|||||||
@@ -254,10 +254,10 @@ const createParser = (filterType: FilterType) => {
|
|||||||
eq: r => word('=').then(r.value).map(binaryCondition('=')),
|
eq: r => word('=').then(r.value).map(binaryCondition('=')),
|
||||||
ne: r => word('!=').then(r.value).map(binaryCondition('<>')),
|
ne: r => word('!=').then(r.value).map(binaryCondition('<>')),
|
||||||
ne2: r => word('<>').then(r.value).map(binaryCondition('<>')),
|
ne2: r => word('<>').then(r.value).map(binaryCondition('<>')),
|
||||||
lt: r => word('<').then(r.value).map(binaryCondition('<')),
|
|
||||||
gt: r => word('>').then(r.value).map(binaryCondition('>')),
|
|
||||||
le: r => word('<=').then(r.value).map(binaryCondition('<=')),
|
le: r => word('<=').then(r.value).map(binaryCondition('<=')),
|
||||||
ge: r => word('>=').then(r.value).map(binaryCondition('>=')),
|
ge: r => word('>=').then(r.value).map(binaryCondition('>=')),
|
||||||
|
lt: r => word('<').then(r.value).map(binaryCondition('<')),
|
||||||
|
gt: r => word('>').then(r.value).map(binaryCondition('>')),
|
||||||
startsWith: r => word('^').then(r.value).map(likeCondition('like', '#VALUE#%')),
|
startsWith: r => word('^').then(r.value).map(likeCondition('like', '#VALUE#%')),
|
||||||
endsWith: r => word('$').then(r.value).map(likeCondition('like', '%#VALUE#')),
|
endsWith: r => word('$').then(r.value).map(likeCondition('like', '%#VALUE#')),
|
||||||
contains: r => word('+').then(r.value).map(likeCondition('like', '%#VALUE#%')),
|
contains: r => word('+').then(r.value).map(likeCondition('like', '%#VALUE#%')),
|
||||||
@@ -271,24 +271,30 @@ const createParser = (filterType: FilterType) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const allowedValues = []; // 'string1', 'string2', 'number', 'noQuotedString'];
|
const allowedValues = []; // 'string1', 'string2', 'number', 'noQuotedString'];
|
||||||
if (filterType == 'string') allowedValues.push('string1', 'string2', 'noQuotedString');
|
if (filterType == 'string' || filterType == 'eval') {
|
||||||
if (filterType == 'number') allowedValues.push('string1Num', 'string2Num', 'number');
|
allowedValues.push('string1', 'string2', 'noQuotedString');
|
||||||
|
}
|
||||||
|
if (filterType == 'number') {
|
||||||
|
allowedValues.push('string1Num', 'string2Num', 'number');
|
||||||
|
}
|
||||||
|
|
||||||
const allowedElements = ['null', 'notNull', 'eq', 'ne', 'ne2'];
|
const allowedElements = ['null', 'notNull', 'eq', 'ne', 'ne2'];
|
||||||
if (filterType == 'number' || filterType == 'datetime') allowedElements.push('lt', 'gt', 'le', 'ge');
|
if (filterType == 'number' || filterType == 'datetime' || filterType == 'eval') {
|
||||||
if (filterType == 'string')
|
allowedElements.push('le', 'ge', 'lt', 'gt');
|
||||||
allowedElements.push(
|
}
|
||||||
'empty',
|
if (filterType == 'string') {
|
||||||
'notEmpty',
|
allowedElements.push('empty', 'notEmpty');
|
||||||
'startsWith',
|
}
|
||||||
'endsWith',
|
if (filterType == 'eval' || filterType == 'string') {
|
||||||
'contains',
|
allowedElements.push('startsWith', 'endsWith', 'contains', 'startsWithNot', 'endsWithNot', 'containsNot');
|
||||||
'startsWithNot',
|
}
|
||||||
'endsWithNot',
|
if (filterType == 'logical') {
|
||||||
'containsNot'
|
allowedElements.push('true', 'false', 'trueNum', 'falseNum');
|
||||||
);
|
}
|
||||||
if (filterType == 'logical') allowedElements.push('true', 'false', 'trueNum', 'falseNum');
|
if (filterType == 'eval') {
|
||||||
if (filterType == 'datetime')
|
allowedElements.push('true', 'false');
|
||||||
|
}
|
||||||
|
if (filterType == 'datetime') {
|
||||||
allowedElements.push(
|
allowedElements.push(
|
||||||
'yearMonthDaySecond',
|
'yearMonthDaySecond',
|
||||||
'yearMonthDayMinute',
|
'yearMonthDayMinute',
|
||||||
@@ -308,10 +314,13 @@ const createParser = (filterType: FilterType) => {
|
|||||||
'thisYear',
|
'thisYear',
|
||||||
'nextYear'
|
'nextYear'
|
||||||
);
|
);
|
||||||
|
}
|
||||||
// must be last
|
// must be last
|
||||||
if (filterType == 'string') allowedElements.push('valueTestStr');
|
if (filterType == 'string' || filterType == 'eval') {
|
||||||
else allowedElements.push('valueTestEq');
|
allowedElements.push('valueTestStr');
|
||||||
|
} else {
|
||||||
|
allowedElements.push('valueTestEq');
|
||||||
|
}
|
||||||
|
|
||||||
return P.createLanguage(langDef);
|
return P.createLanguage(langDef);
|
||||||
};
|
};
|
||||||
@@ -321,6 +330,7 @@ const parsers = {
|
|||||||
string: createParser('string'),
|
string: createParser('string'),
|
||||||
datetime: createParser('datetime'),
|
datetime: createParser('datetime'),
|
||||||
logical: createParser('logical'),
|
logical: createParser('logical'),
|
||||||
|
eval: createParser('eval'),
|
||||||
mongo: mongoParser,
|
mongo: mongoParser,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
// import types from 'dbgate-types';
|
// import types from 'dbgate-types';
|
||||||
|
|
||||||
export type FilterType = 'number' | 'string' | 'datetime' | 'logical' | 'mongo';
|
export type FilterType = 'number' | 'string' | 'datetime' | 'logical' | 'eval' | 'mongo';
|
||||||
|
|||||||
@@ -161,6 +161,33 @@
|
|||||||
{ onClick: () => setFilter('TRUE'), text: 'Is True' },
|
{ onClick: () => setFilter('TRUE'), text: 'Is True' },
|
||||||
{ onClick: () => setFilter('FALSE'), text: 'Is False' },
|
{ onClick: () => setFilter('FALSE'), text: 'Is False' },
|
||||||
];
|
];
|
||||||
|
case 'eval':
|
||||||
|
return [
|
||||||
|
{ onClick: () => setFilter(''), text: 'Clear Filter' },
|
||||||
|
{ onClick: () => filterMultipleValues(), text: 'Filter multiple values' },
|
||||||
|
|
||||||
|
{ onClick: () => openFilterWindow('='), text: 'Equals...' },
|
||||||
|
{ onClick: () => openFilterWindow('<>'), text: 'Does Not Equal...' },
|
||||||
|
{ onClick: () => setFilter('NULL'), text: 'Is Null' },
|
||||||
|
{ onClick: () => setFilter('NOT NULL'), text: 'Is Not Null' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
{ onClick: () => openFilterWindow('>'), text: 'Greater Than...' },
|
||||||
|
{ onClick: () => openFilterWindow('>='), text: 'Greater Than Or Equal To...' },
|
||||||
|
{ onClick: () => openFilterWindow('<'), text: 'Less Than...' },
|
||||||
|
{ onClick: () => openFilterWindow('<='), text: 'Less Than Or Equal To...' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
|
||||||
|
{ onClick: () => openFilterWindow('+'), text: 'Contains...' },
|
||||||
|
{ onClick: () => openFilterWindow('~'), text: 'Does Not Contain...' },
|
||||||
|
{ onClick: () => openFilterWindow('^'), text: 'Begins With...' },
|
||||||
|
{ onClick: () => openFilterWindow('!^'), text: 'Does Not Begin With...' },
|
||||||
|
{ onClick: () => openFilterWindow('$'), text: 'Ends With...' },
|
||||||
|
{ onClick: () => openFilterWindow('!$'), text: 'Does Not End With...' },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// return [
|
// return [
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
export let display;
|
export let display;
|
||||||
export let changeSetState;
|
export let changeSetState;
|
||||||
export let dispatchChangeSet;
|
export let dispatchChangeSet;
|
||||||
|
export let useEvalFilters = false;
|
||||||
|
|
||||||
export let isDetailView = false;
|
export let isDetailView = false;
|
||||||
export let showReferences = false;
|
export let showReferences = false;
|
||||||
@@ -181,7 +182,7 @@
|
|||||||
height={'30%'}
|
height={'30%'}
|
||||||
skip={!isDynamicStructure || !display?.filterable}
|
skip={!isDynamicStructure || !display?.filterable}
|
||||||
>
|
>
|
||||||
<JsonViewFilters {...$$props} {managerSize} {isDynamicStructure} />
|
<JsonViewFilters {...$$props} {managerSize} {isDynamicStructure} {useEvalFilters} />
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
|
|
||||||
<WidgetColumnBarItem
|
<WidgetColumnBarItem
|
||||||
@@ -191,7 +192,7 @@
|
|||||||
skip={!display?.filterable || isDynamicStructure || display.filterCount == 0 || isFormView}
|
skip={!display?.filterable || isDynamicStructure || display.filterCount == 0 || isFormView}
|
||||||
collapsed={isDetailView}
|
collapsed={isDetailView}
|
||||||
>
|
>
|
||||||
<JsonViewFilters {...$$props} {managerSize} {isDynamicStructure} />
|
<JsonViewFilters {...$$props} {managerSize} {isDynamicStructure} {useEvalFilters} />
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
|
|
||||||
<WidgetColumnBarItem
|
<WidgetColumnBarItem
|
||||||
|
|||||||
@@ -335,6 +335,7 @@
|
|||||||
export let multipleGridsOnTab = false;
|
export let multipleGridsOnTab = false;
|
||||||
export let tabControlHiddenTab = false;
|
export let tabControlHiddenTab = false;
|
||||||
export let onCustomGridRefresh;
|
export let onCustomGridRefresh;
|
||||||
|
export let useEvalFilters = false;
|
||||||
// export let generalAllowSave = false;
|
// export let generalAllowSave = false;
|
||||||
|
|
||||||
export const activator = createActivator('DataGridCore', false);
|
export const activator = createActivator('DataGridCore', false);
|
||||||
@@ -1548,7 +1549,7 @@
|
|||||||
{conid}
|
{conid}
|
||||||
{database}
|
{database}
|
||||||
driver={display?.driver}
|
driver={display?.driver}
|
||||||
filterType={col.filterType || getFilterType(col.dataType)}
|
filterType={useEvalFilters ? 'eval' : col.filterType || getFilterType(col.dataType)}
|
||||||
filter={display.getFilter(col.uniqueName)}
|
filter={display.getFilter(col.uniqueName)}
|
||||||
setFilter={value => display.setFilter(col.uniqueName, value)}
|
setFilter={value => display.setFilter(col.uniqueName, value)}
|
||||||
showResizeSplitter
|
showResizeSplitter
|
||||||
|
|||||||
@@ -58,5 +58,6 @@
|
|||||||
gridCoreComponent={JslDataGridCore}
|
gridCoreComponent={JslDataGridCore}
|
||||||
bind:loadedRows
|
bind:loadedRows
|
||||||
isDynamicStructure={$info?.__isDynamicStructure}
|
isDynamicStructure={$info?.__isDynamicStructure}
|
||||||
|
useEvalFilters
|
||||||
/>
|
/>
|
||||||
{/key}
|
{/key}
|
||||||
|
|||||||
@@ -10,8 +10,10 @@
|
|||||||
export let display;
|
export let display;
|
||||||
export let filters;
|
export let filters;
|
||||||
export let isDynamicStructure;
|
export let isDynamicStructure;
|
||||||
|
export let useEvalFilters;
|
||||||
|
|
||||||
function computeFilterType(isDynamicStructure, display, uniqueName) {
|
function computeFilterType(isDynamicStructure, display, uniqueName, useEvalFilters) {
|
||||||
|
if (useEvalFilters) return 'eval';
|
||||||
if (isDynamicStructure) return 'mongo';
|
if (isDynamicStructure) return 'mongo';
|
||||||
const col = display.findColumn(uniqueName);
|
const col = display.findColumn(uniqueName);
|
||||||
if (col) {
|
if (col) {
|
||||||
@@ -35,7 +37,7 @@
|
|||||||
</InlineButton>
|
</InlineButton>
|
||||||
</div>
|
</div>
|
||||||
<DataFilterControl
|
<DataFilterControl
|
||||||
filterType={computeFilterType(isDynamicStructure, display, uniqueName)}
|
filterType={computeFilterType(isDynamicStructure, display, uniqueName, useEvalFilters)}
|
||||||
filter={filters[uniqueName]}
|
filter={filters[uniqueName]}
|
||||||
setFilter={value => display.setFilter(uniqueName, value)}
|
setFilter={value => display.setFilter(uniqueName, value)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
export let managerSize;
|
export let managerSize;
|
||||||
export let display;
|
export let display;
|
||||||
export let isDynamicStructure;
|
export let isDynamicStructure;
|
||||||
|
export let useEvalFilters;
|
||||||
|
|
||||||
$: filters = display?.config?.filters;
|
$: filters = display?.config?.filters;
|
||||||
|
|
||||||
@@ -15,6 +16,6 @@
|
|||||||
|
|
||||||
<ManagerInnerContainer width={managerSize}>
|
<ManagerInnerContainer width={managerSize}>
|
||||||
{#each allFilterNames as uniqueName}
|
{#each allFilterNames as uniqueName}
|
||||||
<JsonViewFilterColumn {uniqueName} {display} {filters} {isDynamicStructure} />
|
<JsonViewFilterColumn {uniqueName} {display} {filters} {isDynamicStructure} {useEvalFilters} />
|
||||||
{/each}
|
{/each}
|
||||||
</ManagerInnerContainer>
|
</ManagerInnerContainer>
|
||||||
|
|||||||
@@ -54,6 +54,21 @@
|
|||||||
{ value: '$', label: 'ends with' },
|
{ value: '$', label: 'ends with' },
|
||||||
{ value: '!$', label: 'does not end with' },
|
{ value: '!$', label: 'does not end with' },
|
||||||
];
|
];
|
||||||
|
case 'eval':
|
||||||
|
return [
|
||||||
|
{ value: '=', label: 'eqals' },
|
||||||
|
{ value: '<>', label: 'does not equal' },
|
||||||
|
{ value: '<', label: 'is smaller' },
|
||||||
|
{ value: '>', label: 'is greater' },
|
||||||
|
{ value: '<=', label: 'is smaller or equal' },
|
||||||
|
{ value: '>=', label: 'is greater or equal' },
|
||||||
|
{ value: '+', label: 'contains' },
|
||||||
|
{ value: '~', label: 'does not contain' },
|
||||||
|
{ value: '^', label: 'begins with' },
|
||||||
|
{ value: '!^', label: 'does not begin with' },
|
||||||
|
{ value: '$', label: 'ends with' },
|
||||||
|
{ value: '!$', label: 'does not end with' },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user