Commit 4b5bfd3d by Alexander Zobnin

azuremonitor: more autocomplete suggestions for built-in functions

parent 99ff8e68
......@@ -96,57 +96,51 @@ export default class KustoQueryField extends QueryField {
const wrapperClasses = wrapperNode.classList;
let typeaheadContext: string | null = null;
// Built-in functions
if (wrapperClasses.contains('function-context')) {
typeaheadContext = 'context-function';
if (this.fields) {
suggestionGroups = this.getKeywordSuggestions();
} else {
this._fetchFields();
return;
}
suggestionGroups = this.getColumnSuggestions();
// where
} else if (modelPrefix.match(/(where\s(\w+\b)?$)/i)) {
typeaheadContext = 'context-where';
const fullQuery = Plain.serialize(this.state.value);
const table = this.getTableFromContext(fullQuery);
if (table) {
suggestionGroups = this.getWhereSuggestions(table);
} else {
return;
}
} else if (modelPrefix.match(/(,\s*$)/)) {
typeaheadContext = 'context-multiple-fields';
if (this.fields) {
suggestionGroups = this.getKeywordSuggestions();
} else {
this._fetchFields();
return;
}
} else if (modelPrefix.match(/(from\s$)/i)) {
typeaheadContext = 'context-from';
if (this.events) {
suggestionGroups = this.getKeywordSuggestions();
} else {
this._fetchEvents();
return;
}
} else if (modelPrefix.match(/(^select\s\w*$)/i)) {
typeaheadContext = 'context-select';
if (this.fields) {
suggestionGroups = this.getKeywordSuggestions();
} else {
this._fetchFields();
return;
}
} else if (modelPrefix.match(/from\s\S+\s\w*$/i)) {
prefix = '';
typeaheadContext = 'context-since';
suggestionGroups = this.getKeywordSuggestions();
// } else if (modelPrefix.match(/\d+\s\w*$/)) {
// typeaheadContext = 'context-number';
// suggestionGroups = this._getAfterNumberSuggestions();
} else if (modelPrefix.match(/ago\b/i) || modelPrefix.match(/facet\b/i) || modelPrefix.match(/\$__timefilter\b/i)) {
typeaheadContext = 'context-timeseries';
suggestionGroups = this.getKeywordSuggestions();
suggestionGroups = this.getColumnSuggestions();
// summarize by
} else if (modelPrefix.match(/(summarize\s(\w+\b)?$)/i)) {
typeaheadContext = 'context-summarize';
suggestionGroups = this.getFunctionSuggestions();
} else if (modelPrefix.match(/(summarize\s(.+\s)?by\s+([^,\s]+,\s*)*([^,\s]+\b)?$)/i)) {
typeaheadContext = 'context-summarize-by';
suggestionGroups = this.getColumnSuggestions();
// order by, top X by, ... by ...
} else if (modelPrefix.match(/(by\s+([^,\s]+,\s*)*([^,\s]+\b)?$)/i)) {
typeaheadContext = 'context-by';
suggestionGroups = this.getColumnSuggestions();
// join
} else if (modelPrefix.match(/(on\s(.+\b)?$)/i)) {
typeaheadContext = 'context-join-on';
suggestionGroups = this.getColumnSuggestions();
} else if (modelPrefix.match(/(join\s+(\(\s+)?(\w+\b)?$)/i)) {
typeaheadContext = 'context-join';
suggestionGroups = this.getTableSuggestions();
// distinct
} else if (modelPrefix.match(/(distinct\s(.+\b)?$)/i)) {
typeaheadContext = 'context-distinct';
suggestionGroups = this.getColumnSuggestions();
// database()
} else if (modelPrefix.match(/(database\(\"(\w+)\"\)\.(.+\b)?$)/i)) {
typeaheadContext = 'context-database-table';
const db = this.getDBFromDatabaseFunction(modelPrefix);
console.log(db);
suggestionGroups = this.getTableSuggestions(db);
prefix = prefix.replace('.', '');
// built-in
} else if (prefix && !wrapperClasses.contains('argument')) {
if (modelPrefix.match(/\s$/i)) {
prefix = '';
......@@ -156,7 +150,7 @@ export default class KustoQueryField extends QueryField {
} else if (Plain.serialize(this.state.value) === '') {
typeaheadContext = 'context-new';
if (this.schema) {
suggestionGroups = this._getInitialSuggestions();
suggestionGroups = this.getInitialSuggestions();
} else {
this.fetchSchema();
setTimeout(this.onTypeahead, 0);
......@@ -187,7 +181,7 @@ export default class KustoQueryField extends QueryField {
.filter(group => group.items.length > 0);
// console.log('onTypeahead', selection.anchorNode, wrapperClasses, text, offset, prefix, typeaheadContext);
// console.log('onTypeahead', modelPrefix, prefix, typeaheadContext);
console.log('onTypeahead', modelPrefix, prefix, typeaheadContext);
this.setState({
typeaheadPrefix: prefix,
......@@ -293,6 +287,10 @@ export default class KustoQueryField extends QueryField {
// ];
// }
private getInitialSuggestions(): SuggestionGroup[] {
return this.getTableSuggestions();
}
private getKeywordSuggestions(): SuggestionGroup[] {
return [
{
......@@ -323,50 +321,28 @@ export default class KustoQueryField extends QueryField {
];
}
private _getInitialSuggestions(): SuggestionGroup[] {
private getFunctionSuggestions(): SuggestionGroup[] {
return [
{
prefixMatch: true,
label: 'Tables',
items: _.map(this.schema.Databases.Default.Tables, (t: any) => ({ text: t.Name }))
label: 'Functions',
items: functionTokens.map((s: any) => { s.type = 'function'; return s; })
},
{
prefixMatch: true,
label: 'Macros',
items: grafanaMacros.map((s: any) => { s.type = 'function'; return s; })
}
];
// return [
// {
// prefixMatch: true,
// label: 'Keywords',
// items: KEYWORDS.map(wrapText)
// },
// {
// prefixMatch: true,
// label: 'Operators',
// items: operatorTokens.map((s: any) => { s.type = 'function'; return s; })
// },
// {
// prefixMatch: true,
// label: 'Functions',
// items: functionTokens.map((s: any) => { s.type = 'function'; return s; })
// },
// {
// prefixMatch: true,
// label: 'Macros',
// items: grafanaMacros.map((s: any) => { s.type = 'function'; return s; })
// }
// ];
}
private getWhereSuggestions(table: string): SuggestionGroup[] {
const tableSchema = this.schema.Databases.Default.Tables[table];
if (tableSchema) {
getTableSuggestions(db = 'Default'): SuggestionGroup[] {
if (this.schema.Databases[db]) {
return [
{
prefixMatch: true,
label: 'Fields',
items: _.map(tableSchema.OrderedColumns, (f: any) => ({
text: f.Name,
hint: f.Type
}))
label: 'Tables',
items: _.map(this.schema.Databases[db].Tables, (t: any) => ({ text: t.Name }))
}
];
} else {
......@@ -374,7 +350,28 @@ export default class KustoQueryField extends QueryField {
}
}
private getTableFromContext(query: string) {
private getColumnSuggestions(): SuggestionGroup[] {
const table = this.getTableFromContext();
if (table) {
const tableSchema = this.schema.Databases.Default.Tables[table];
if (tableSchema) {
return [
{
prefixMatch: true,
label: 'Fields',
items: _.map(tableSchema.OrderedColumns, (f: any) => ({
text: f.Name,
hint: f.Type
}))
}
];
}
}
return [];
}
private getTableFromContext() {
const query = Plain.serialize(this.state.value);
const tablePattern = /^\s*(\w+)\s*|/g;
const normalizedQuery = normalizeQuery(query);
const match = tablePattern.exec(normalizedQuery);
......@@ -385,30 +382,14 @@ export default class KustoQueryField extends QueryField {
}
}
private async _fetchEvents() {
// const query = 'events';
// const result = await this.request(query);
// if (result === undefined) {
// this.events = [];
// } else {
// this.events = result;
// }
// setTimeout(this.onTypeahead, 0);
//Stub
this.events = [];
}
private async _fetchFields() {
// const query = 'fields';
// const result = await this.request(query);
// this.fields = result || [];
// setTimeout(this.onTypeahead, 0);
// Stub
this.fields = [];
private getDBFromDatabaseFunction(prefix: string) {
const databasePattern = /database\(\"(\w+)\"\)/gi;
const match = databasePattern.exec(prefix);
if (match && match.length > 1 && match[0] && match[1]) {
return match[1];
} else {
return null;
}
}
private async fetchSchema() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment