Skip to content

Commit

Permalink
Merge branch 'master' into v3.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
mckn committed Aug 27, 2020
2 parents 062f11b + c86000c commit b21dfe8
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "grafana-azure-data-explorer-datasource",
"version": "3.0.1",
"version": "3.0.2",
"description": "Grafana data source for Azure Data Explorer",
"scripts": {
"build": "grafana-toolkit plugin:build",
Expand Down
10 changes: 5 additions & 5 deletions src/QueryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ import { needsToBeMigrated, migrateQuery } from 'migrations/query';
type Props = QueryEditorProps<AdxDataSource, KustoQuery, AdxDataSourceOptions>;

export const QueryEditor: React.FC<Props> = props => {
const { datasource, query } = props;
const { datasource } = props;
const executedQuery = useExecutedQuery(props.data);
const executedQueryError = useExecutedQueryError(props.data);
const dirty = useDirty(props.query.query, executedQuery);
const schema = useAsync(() => datasource.getSchema(), [datasource.id]);
const databases = useDatabaseOptions(schema.value);
const database = useSelectedDatabase(databases, query);
const database = useSelectedDatabase(databases, props.query);
const templateVariables = useTemplateVariables(datasource);
const rawMode = isRawMode(props);

useEffect(() => {
if (needsToBeMigrated(query)) {
props.onChange(migrateQuery(query));
if (needsToBeMigrated(props.query)) {
props.onChange(migrateQuery(props.query));
props.onRunQuery();
}
}, []);
Expand Down Expand Up @@ -105,7 +105,7 @@ export const QueryEditor: React.FC<Props> = props => {
datasource={datasource}
database={database}
onChangeQuery={props.onChange}
query={query}
query={props.query}
schema={schema.value}
templateVariableOptions={templateVariables}
/>
Expand Down
53 changes: 34 additions & 19 deletions src/components/VisualQueryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,22 @@ export const VisualQueryEditor: React.FC<Props> = props => {
if (!table || !table.property) {
return [];
}
return getTableSchema(datasource, database, table);

const schema = await getTableSchema(datasource, database, table);
const from = query.expression.from ?? table;

props.onChangeQuery({
...props.query,
query: kustoExpressionParser.query(
{
...props.query.expression,
from,
},
schema
),
});

return schema;
}, [datasource.id, database, table]);

const onAutoComplete = useCallback(
Expand All @@ -64,26 +79,26 @@ export const VisualQueryEditor: React.FC<Props> = props => {
const columns = useColumnOptions(tableSchema.value);
const groupable = useGroupableColumns(columns);

const onChangeTable = async (expression: QueryEditorExpression) => {
if (!isFieldExpression(expression) || !table) {
return;
}

const columns = await getTableSchema(datasource, database, expression);
const onChangeTable = useCallback(
(expression: QueryEditorExpression) => {
if (!isFieldExpression(expression) || !table) {
return;
}

const next = {
...defaultQuery.expression,
from: expression,
};
const next = {
...defaultQuery.expression,
from: expression,
};

props.onChangeQuery({
...props.query,
resultFormat: resultFormat,
database: database,
expression: next,
query: kustoExpressionParser.query(next, columns),
});
};
props.onChangeQuery({
...props.query,
resultFormat: resultFormat,
database: database,
expression: next,
});
},
[props.onChangeQuery, props.query, resultFormat, database]
);

const onWhereChange = useCallback(
(expression: QueryEditorArrayExpression) => {
Expand Down
4 changes: 2 additions & 2 deletions src/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,14 @@ export class AdxDataSource extends DataSourceWithBackend<KustoQuery, AdxDataSour
}
const queryParts: string[] = [];

const take = 'take 50000';
const where = `where ${columns.map(column => `isnotnull(${column})`).join(' and ')}`;
const sample = `sample 100`;
const project = `project ${columns.map(column => column).join(', ')}`;
const summarize = `summarize ${columns.map(column => `buildschema(${column})`).join(', ')}`;

queryParts.push(table);
queryParts.push(take);
queryParts.push(where);
queryParts.push(sample);
queryParts.push(project);
queryParts.push(summarize);

Expand Down
41 changes: 36 additions & 5 deletions src/schema/AdxAutoComplete.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { KustoQuery, defaultQuery, AdxColumnSchema } from 'types';
import { DataQueryRequest } from '@grafana/data';
import { DataQueryRequest, TimeRange } from '@grafana/data';
import { AdxDataSource } from '../datasource';
import { getTemplateSrv } from '@grafana/runtime';

export class AdxAutoComplete {
constructor(
Expand All @@ -16,11 +17,18 @@ export class AdxAutoComplete {
}

const queryParts: string[] = [];
const defaultTimeColum = findDefaultTimeColumn(this.columnSchema);

queryParts.push(this.table);

if (defaultTimeColum) {
queryParts.push(`where $__timeFilter(${this.castIfDynamic(defaultTimeColum, this.columnSchema)})`);
}

queryParts.push(`where ${column} contains "${searchTerm}"`);
queryParts.push('take 50000');
queryParts.push(`distinct ${this.castIfDynamic(column, this.columnSchema)}`);
queryParts.push(`take 251`);
queryParts.push('take 251');

const kql = queryParts.join('\n| ');

Expand All @@ -35,9 +43,11 @@ export class AdxAutoComplete {
};

const response = await this.datasource
.query({
targets: [query],
} as DataQueryRequest<KustoQuery>)
.query(
includeTimeRange({
targets: [query],
}) as DataQueryRequest<KustoQuery>
)
.toPromise();

if (!Array.isArray(response?.data) || response.data.length === 0) {
Expand Down Expand Up @@ -73,3 +83,24 @@ export class AdxAutoComplete {
}, '');
}
}

const findDefaultTimeColumn = (columns: AdxColumnSchema[]): string | undefined => {
const column = columns?.find(col => col.CslType === 'datetime');
return column?.Name;
};

/**
* this is a suuuper ugly way of doing this.
*/
const includeTimeRange = (option: any): any => {
const range = (getTemplateSrv() as any)?.timeRange as TimeRange;

if (!range) {
return option;
}

return {
...option,
range,
};
};
2 changes: 1 addition & 1 deletion src/schema/AdxSchemaResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class AdxSchemaResolver {
constructor(private datasource: AdxDataSource) {}

private createCacheKey(addition: string): string {
return `${schemaKey}.${this.datasource.meta.id}.${addition}`;
return `${schemaKey}.${this.datasource.id}.${addition}`;
}

async getDatabases(): Promise<AdxDatabaseSchema[]> {
Expand Down

0 comments on commit b21dfe8

Please sign in to comment.