Skip to content

Commit 4afac5f

Browse files
committed
Add query history sorting for remote queries
Also, fix two smaller issues: - Ensure the `Open Query Directory` command opens inside the specified directory. - Ensure label changes are saved across restarts.
1 parent 689db37 commit 4afac5f

2 files changed

Lines changed: 66 additions & 44 deletions

File tree

extensions/ql-vscode/src/query-history.ts

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { URLSearchParams } from 'url';
2828
import { QueryServerClient } from './queryserver-client';
2929
import { DisposableObject } from './pure/disposable-object';
3030
import { commandRunner } from './commandRunner';
31-
import { assertNever, ONE_HOUR_IN_MS, TWO_HOURS_IN_MS, getErrorMessage, getErrorStack } from './pure/helpers-pure';
31+
import { assertNever, ONE_HOUR_IN_MS, TWO_HOURS_IN_MS, getErrorMessage, getErrorStack } from './pure/helpers-pure';
3232
import { CompletedLocalQueryInfo, LocalQueryInfo as LocalQueryInfo, QueryHistoryInfo } from './query-results';
3333
import { DatabaseManager } from './databases';
3434
import { registerQueryHistoryScubber } from './query-history-scrubber';
@@ -181,38 +181,48 @@ export class HistoryTreeDataProvider extends DisposableObject {
181181
): ProviderResult<QueryHistoryInfo[]> {
182182
return element ? [] : this.history.sort((h1, h2) => {
183183

184-
// TODO remote queries are not implemented yet.
185-
if (h1.t !== 'local' && h2.t !== 'local') {
186-
return 0;
187-
}
188-
if (h1.t !== 'local') {
189-
return -1;
190-
}
191-
if (h2.t !== 'local') {
192-
return 1;
193-
}
184+
const h1Label = h1.label.toLowerCase();
185+
const h2Label = h2.label.toLowerCase();
186+
187+
const h1Date = h1.t === 'local'
188+
? h1.initialInfo.start.getTime()
189+
: h1.remoteQuery?.executionStartTime;
190+
191+
const h2Date = h2.t === 'local'
192+
? h2.initialInfo.start.getTime()
193+
: h2.remoteQuery?.executionStartTime;
194194

195-
const resultCount1 = h1.completedQuery?.resultCount ?? -1;
196-
const resultCount2 = h2.completedQuery?.resultCount ?? -1;
195+
// result count for remote queries is not available here.
196+
const resultCount1 = h1.t === 'local'
197+
? h1.completedQuery?.resultCount ?? -1
198+
: -1;
199+
const resultCount2 = h2.t === 'local'
200+
? h2.completedQuery?.resultCount ?? -1
201+
: -1;
197202

198203
switch (this.sortOrder) {
199204
case SortOrder.NameAsc:
200-
return h1.label.localeCompare(h2.label, env.language);
205+
return h1Label.localeCompare(h2Label, env.language);
206+
201207
case SortOrder.NameDesc:
202-
return h2.label.localeCompare(h1.label, env.language);
208+
return h2Label.localeCompare(h1Label, env.language);
209+
203210
case SortOrder.DateAsc:
204-
return h1.initialInfo.start.getTime() - h2.initialInfo.start.getTime();
211+
return h1Date - h2Date;
212+
205213
case SortOrder.DateDesc:
206-
return h2.initialInfo.start.getTime() - h1.initialInfo.start.getTime();
214+
return h2Date - h1Date;
215+
207216
case SortOrder.CountAsc:
208217
// If the result counts are equal, sort by name.
209218
return resultCount1 - resultCount2 === 0
210-
? h1.label.localeCompare(h2.label, env.language)
219+
? h1Label.localeCompare(h2Label, env.language)
211220
: resultCount1 - resultCount2;
221+
212222
case SortOrder.CountDesc:
213223
// If the result counts are equal, sort by name.
214224
return resultCount2 - resultCount1 === 0
215-
? h2.label.localeCompare(h1.label, env.language)
225+
? h2Label.localeCompare(h1Label, env.language)
216226
: resultCount2 - resultCount1;
217227
default:
218228
assertNever(this.sortOrder);
@@ -636,7 +646,7 @@ export class QueryHistoryManager extends DisposableObject {
636646
if (response !== undefined) {
637647
// Interpret empty string response as 'go back to using default'
638648
finalSingleItem.initialInfo.userSpecifiedLabel = response === '' ? undefined : response;
639-
this.treeDataProvider.refresh();
649+
await this.refreshTreeView();
640650
}
641651
}
642652

@@ -727,20 +737,20 @@ export class QueryHistoryManager extends DisposableObject {
727737
return;
728738
}
729739

730-
let p: string | undefined;
740+
let externalFilePath: string | undefined;
731741
if (finalSingleItem.t === 'local') {
732742
if (finalSingleItem.completedQuery) {
733-
p = finalSingleItem.completedQuery.query.querySaveDir;
743+
externalFilePath = path.join(finalSingleItem.completedQuery.query.querySaveDir, 'timestamp');
734744
}
735745
} else if (finalSingleItem.t === 'remote') {
736-
p = path.join(this.queryStorageDir, finalSingleItem.queryId);
746+
externalFilePath = path.join(this.queryStorageDir, finalSingleItem.queryId, 'timestamp');
737747
}
738748

739-
if (p) {
749+
if (externalFilePath) {
740750
try {
741-
await commands.executeCommand('revealFileInOS', Uri.file(p));
751+
await commands.executeCommand('revealFileInOS', Uri.file(externalFilePath));
742752
} catch (e) {
743-
throw new Error(`Failed to open ${p}: ${getErrorMessage(e)}`);
753+
throw new Error(`Failed to open ${externalFilePath}: ${getErrorMessage(e)}`);
744754
}
745755
}
746756
}

extensions/ql-vscode/src/vscode-tests/no-workspace/query-history.test.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,11 @@ describe('query-history', () => {
427427

428428
describe('getChildren', () => {
429429
const history = [
430-
item('a', 10, 20),
431-
item('b', 5, 30),
432-
item('c', 1, 25),
430+
item('a', 2, 'remote'),
431+
item('b', 10, 'local', 20),
432+
item('c', 5, 'local', 30),
433+
item('d', 1, 'local', 25),
434+
item('e', 6, 'remote'),
433435
];
434436
let treeDataProvider: HistoryTreeDataProvider;
435437

@@ -456,31 +458,31 @@ describe('query-history', () => {
456458
});
457459

458460
it('should get children for date ascending', async () => {
459-
const expected = [history[2], history[1], history[0]];
461+
const expected = [history[3], history[0], history[2], history[4], history[1]];
460462
treeDataProvider.sortOrder = SortOrder.DateAsc;
461463

462464
const children = await treeDataProvider.getChildren();
463465
expect(children).to.deep.eq(expected);
464466
});
465467

466468
it('should get children for date descending', async () => {
467-
const expected = [history[0], history[1], history[2]];
469+
const expected = [history[3], history[0], history[2], history[4], history[1]].reverse();
468470
treeDataProvider.sortOrder = SortOrder.DateDesc;
469471

470472
const children = await treeDataProvider.getChildren();
471473
expect(children).to.deep.eq(expected);
472474
});
473475

474476
it('should get children for result count ascending', async () => {
475-
const expected = [history[0], history[2], history[1]];
477+
const expected = [history[0], history[4], history[1], history[3], history[2]];
476478
treeDataProvider.sortOrder = SortOrder.CountAsc;
477479

478480
const children = await treeDataProvider.getChildren();
479481
expect(children).to.deep.eq(expected);
480482
});
481483

482484
it('should get children for result count descending', async () => {
483-
const expected = [history[1], history[2], history[0]];
485+
const expected = [history[0], history[4], history[1], history[3], history[2]].reverse();
484486
treeDataProvider.sortOrder = SortOrder.CountDesc;
485487

486488
const children = await treeDataProvider.getChildren();
@@ -509,17 +511,27 @@ describe('query-history', () => {
509511
expect(children).to.deep.eq(expected);
510512
});
511513

512-
function item(label: string, start: number, resultCount?: number) {
513-
return {
514-
label,
515-
initialInfo: {
516-
start: new Date(start),
517-
},
518-
completedQuery: {
519-
resultCount,
520-
},
521-
t: 'local'
522-
};
514+
function item(label: string, start: number, t = 'local', resultCount?: number) {
515+
if (t === 'local') {
516+
return {
517+
label,
518+
initialInfo: {
519+
start: new Date(start),
520+
},
521+
completedQuery: {
522+
resultCount,
523+
},
524+
t
525+
};
526+
} else {
527+
return {
528+
label,
529+
remoteQuery: {
530+
executionStartTime: start,
531+
},
532+
t
533+
};
534+
}
523535
}
524536
});
525537

0 commit comments

Comments
 (0)