|
1 | 1 | import * as path from 'path';
|
| 2 | +import * as fs from 'fs-extra'; |
2 | 3 | import {
|
3 | 4 | commands,
|
4 | 5 | Disposable,
|
@@ -28,7 +29,7 @@ import { URLSearchParams } from 'url';
|
28 | 29 | import { QueryServerClient } from './queryserver-client';
|
29 | 30 | import { DisposableObject } from './pure/disposable-object';
|
30 | 31 | import { commandRunner } from './commandRunner';
|
31 |
| -import { assertNever, ONE_HOUR_IN_MS, TWO_HOURS_IN_MS, getErrorMessage, getErrorStack } from './pure/helpers-pure'; |
| 32 | +import { assertNever, ONE_HOUR_IN_MS, TWO_HOURS_IN_MS, getErrorMessage, getErrorStack } from './pure/helpers-pure'; |
32 | 33 | import { CompletedLocalQueryInfo, LocalQueryInfo as LocalQueryInfo, QueryHistoryInfo } from './query-results';
|
33 | 34 | import { DatabaseManager } from './databases';
|
34 | 35 | import { registerQueryHistoryScubber } from './query-history-scrubber';
|
@@ -183,38 +184,48 @@ export class HistoryTreeDataProvider extends DisposableObject {
|
183 | 184 | ): ProviderResult<QueryHistoryInfo[]> {
|
184 | 185 | return element ? [] : this.history.sort((h1, h2) => {
|
185 | 186 |
|
186 |
| - // TODO remote queries are not implemented yet. |
187 |
| - if (h1.t !== 'local' && h2.t !== 'local') { |
188 |
| - return 0; |
189 |
| - } |
190 |
| - if (h1.t !== 'local') { |
191 |
| - return -1; |
192 |
| - } |
193 |
| - if (h2.t !== 'local') { |
194 |
| - return 1; |
195 |
| - } |
| 187 | + const h1Label = h1.label.toLowerCase(); |
| 188 | + const h2Label = h2.label.toLowerCase(); |
196 | 189 |
|
197 |
| - const resultCount1 = h1.completedQuery?.resultCount ?? -1; |
198 |
| - const resultCount2 = h2.completedQuery?.resultCount ?? -1; |
| 190 | + const h1Date = h1.t === 'local' |
| 191 | + ? h1.initialInfo.start.getTime() |
| 192 | + : h1.remoteQuery?.executionStartTime; |
| 193 | + |
| 194 | + const h2Date = h2.t === 'local' |
| 195 | + ? h2.initialInfo.start.getTime() |
| 196 | + : h2.remoteQuery?.executionStartTime; |
| 197 | + |
| 198 | + // result count for remote queries is not available here. |
| 199 | + const resultCount1 = h1.t === 'local' |
| 200 | + ? h1.completedQuery?.resultCount ?? -1 |
| 201 | + : -1; |
| 202 | + const resultCount2 = h2.t === 'local' |
| 203 | + ? h2.completedQuery?.resultCount ?? -1 |
| 204 | + : -1; |
199 | 205 |
|
200 | 206 | switch (this.sortOrder) {
|
201 | 207 | case SortOrder.NameAsc:
|
202 |
| - return h1.label.localeCompare(h2.label, env.language); |
| 208 | + return h1Label.localeCompare(h2Label, env.language); |
| 209 | + |
203 | 210 | case SortOrder.NameDesc:
|
204 |
| - return h2.label.localeCompare(h1.label, env.language); |
| 211 | + return h2Label.localeCompare(h1Label, env.language); |
| 212 | + |
205 | 213 | case SortOrder.DateAsc:
|
206 |
| - return h1.initialInfo.start.getTime() - h2.initialInfo.start.getTime(); |
| 214 | + return h1Date - h2Date; |
| 215 | + |
207 | 216 | case SortOrder.DateDesc:
|
208 |
| - return h2.initialInfo.start.getTime() - h1.initialInfo.start.getTime(); |
| 217 | + return h2Date - h1Date; |
| 218 | + |
209 | 219 | case SortOrder.CountAsc:
|
210 | 220 | // If the result counts are equal, sort by name.
|
211 | 221 | return resultCount1 - resultCount2 === 0
|
212 |
| - ? h1.label.localeCompare(h2.label, env.language) |
| 222 | + ? h1Label.localeCompare(h2Label, env.language) |
213 | 223 | : resultCount1 - resultCount2;
|
| 224 | + |
214 | 225 | case SortOrder.CountDesc:
|
215 | 226 | // If the result counts are equal, sort by name.
|
216 | 227 | return resultCount2 - resultCount1 === 0
|
217 |
| - ? h2.label.localeCompare(h1.label, env.language) |
| 228 | + ? h2Label.localeCompare(h1Label, env.language) |
218 | 229 | : resultCount2 - resultCount1;
|
219 | 230 | default:
|
220 | 231 | assertNever(this.sortOrder);
|
@@ -650,7 +661,7 @@ export class QueryHistoryManager extends DisposableObject {
|
650 | 661 | if (response !== undefined) {
|
651 | 662 | // Interpret empty string response as 'go back to using default'
|
652 | 663 | finalSingleItem.initialInfo.userSpecifiedLabel = response === '' ? undefined : response;
|
653 |
| - this.treeDataProvider.refresh(); |
| 664 | + await this.refreshTreeView(); |
654 | 665 | }
|
655 | 666 | }
|
656 | 667 |
|
@@ -741,20 +752,28 @@ export class QueryHistoryManager extends DisposableObject {
|
741 | 752 | return;
|
742 | 753 | }
|
743 | 754 |
|
744 |
| - let p: string | undefined; |
| 755 | + let externalFilePath: string | undefined; |
745 | 756 | if (finalSingleItem.t === 'local') {
|
746 | 757 | if (finalSingleItem.completedQuery) {
|
747 |
| - p = finalSingleItem.completedQuery.query.querySaveDir; |
| 758 | + externalFilePath = path.join(finalSingleItem.completedQuery.query.querySaveDir, 'timestamp'); |
748 | 759 | }
|
749 | 760 | } else if (finalSingleItem.t === 'remote') {
|
750 |
| - p = path.join(this.queryStorageDir, finalSingleItem.queryId); |
| 761 | + externalFilePath = path.join(this.queryStorageDir, finalSingleItem.queryId, 'timestamp'); |
751 | 762 | }
|
752 | 763 |
|
753 |
| - if (p) { |
| 764 | + if (externalFilePath) { |
| 765 | + if (!(await fs.pathExists(externalFilePath))) { |
| 766 | + // timestamp file is missing (manually deleted?) try selecting the parent folder. |
| 767 | + // It's less nice, but at least it will work. |
| 768 | + externalFilePath = path.dirname(externalFilePath); |
| 769 | + if (!(await fs.pathExists(externalFilePath))) { |
| 770 | + throw new Error(`Query directory does not exist: ${externalFilePath}`); |
| 771 | + } |
| 772 | + } |
754 | 773 | try {
|
755 |
| - await commands.executeCommand('revealFileInOS', Uri.file(p)); |
| 774 | + await commands.executeCommand('revealFileInOS', Uri.file(externalFilePath)); |
756 | 775 | } catch (e) {
|
757 |
| - throw new Error(`Failed to open ${p}: ${getErrorMessage(e)}`); |
| 776 | + throw new Error(`Failed to open ${externalFilePath}: ${getErrorMessage(e)}`); |
758 | 777 | }
|
759 | 778 | }
|
760 | 779 | }
|
|
0 commit comments