|
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