mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-25 15:06:55 +00:00
Remove QueryUtils.queryAll and fix test (#885)
This commit is contained in:
parent
b0bbeb188a
commit
0a1a2bf421
@ -1,4 +1,3 @@
|
|||||||
import { ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
|
||||||
import * as _ from "underscore";
|
import * as _ from "underscore";
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import * as ViewModels from "../Contracts/ViewModels";
|
import * as ViewModels from "../Contracts/ViewModels";
|
||||||
@ -7,13 +6,11 @@ import DocumentsTab from "../Explorer/Tabs/DocumentsTab";
|
|||||||
import DocumentId from "../Explorer/Tree/DocumentId";
|
import DocumentId from "../Explorer/Tree/DocumentId";
|
||||||
import { userContext } from "../UserContext";
|
import { userContext } from "../UserContext";
|
||||||
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
|
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
|
||||||
import * as QueryUtils from "../Utils/QueryUtils";
|
|
||||||
import { BackendDefaults, HttpStatusCodes, SavedQueries } from "./Constants";
|
import { BackendDefaults, HttpStatusCodes, SavedQueries } from "./Constants";
|
||||||
import { createCollection } from "./dataAccess/createCollection";
|
import { createCollection } from "./dataAccess/createCollection";
|
||||||
import { createDocument } from "./dataAccess/createDocument";
|
import { createDocument } from "./dataAccess/createDocument";
|
||||||
import { deleteDocument } from "./dataAccess/deleteDocument";
|
import { deleteDocument } from "./dataAccess/deleteDocument";
|
||||||
import { queryDocuments } from "./dataAccess/queryDocuments";
|
import { queryDocuments } from "./dataAccess/queryDocuments";
|
||||||
import { queryDocumentsPage } from "./dataAccess/queryDocumentsPage";
|
|
||||||
import { handleError } from "./ErrorHandlingUtils";
|
import { handleError } from "./ErrorHandlingUtils";
|
||||||
|
|
||||||
export class QueriesClient {
|
export class QueriesClient {
|
||||||
@ -100,45 +97,35 @@ export class QueriesClient {
|
|||||||
|
|
||||||
const options: any = { enableCrossPartitionQuery: true };
|
const options: any = { enableCrossPartitionQuery: true };
|
||||||
const clearMessage = NotificationConsoleUtils.logConsoleProgress("Fetching saved queries");
|
const clearMessage = NotificationConsoleUtils.logConsoleProgress("Fetching saved queries");
|
||||||
const queryIterator: QueryIterator<ItemDefinition & Resource> = queryDocuments(
|
const results = await queryDocuments(
|
||||||
SavedQueries.DatabaseName,
|
SavedQueries.DatabaseName,
|
||||||
SavedQueries.CollectionName,
|
SavedQueries.CollectionName,
|
||||||
this.fetchQueriesQuery(),
|
this.fetchQueriesQuery(),
|
||||||
options
|
options
|
||||||
);
|
).fetchAll();
|
||||||
const fetchQueries = async (firstItemIndex: number): Promise<ViewModels.QueryResults> =>
|
|
||||||
await queryDocumentsPage(queriesCollection.id(), queryIterator, firstItemIndex);
|
let queries: DataModels.Query[] = _.map(results.resources, (document: DataModels.Query) => {
|
||||||
return QueryUtils.queryAllPages(fetchQueries)
|
if (!document) {
|
||||||
.then(
|
return undefined;
|
||||||
(results: ViewModels.QueryResults) => {
|
}
|
||||||
let queries: DataModels.Query[] = _.map(results.documents, (document: DataModels.Query) => {
|
const { id, resourceId, query, queryName } = document;
|
||||||
if (!document) {
|
const parsedQuery: DataModels.Query = {
|
||||||
return undefined;
|
resourceId: resourceId,
|
||||||
}
|
queryName: queryName,
|
||||||
const { id, resourceId, query, queryName } = document;
|
query: query,
|
||||||
const parsedQuery: DataModels.Query = {
|
id: id,
|
||||||
resourceId: resourceId,
|
};
|
||||||
queryName: queryName,
|
try {
|
||||||
query: query,
|
this.validateQuery(parsedQuery);
|
||||||
id: id,
|
return parsedQuery;
|
||||||
};
|
} catch (error) {
|
||||||
try {
|
return undefined;
|
||||||
this.validateQuery(parsedQuery);
|
}
|
||||||
return parsedQuery;
|
});
|
||||||
} catch (error) {
|
queries = _.reject(queries, (parsedQuery: DataModels.Query) => !parsedQuery);
|
||||||
return undefined;
|
NotificationConsoleUtils.logConsoleInfo("Successfully fetched saved queries");
|
||||||
}
|
clearMessage();
|
||||||
});
|
return queries;
|
||||||
queries = _.reject(queries, (parsedQuery: DataModels.Query) => !parsedQuery);
|
|
||||||
NotificationConsoleUtils.logConsoleInfo("Successfully fetched saved queries");
|
|
||||||
return Promise.resolve(queries);
|
|
||||||
},
|
|
||||||
(error: any) => {
|
|
||||||
handleError(error, "getSavedQueries", "Failed to fetch saved queries");
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.finally(() => clearMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deleteQuery(query: DataModels.Query): Promise<void> {
|
public async deleteQuery(query: DataModels.Query): Promise<void> {
|
||||||
|
@ -91,97 +91,11 @@ describe("Query Utils", () => {
|
|||||||
expect(queryStub.getCall(1).args[0]).toBe(0);
|
expect(queryStub.getCall(1).args[0]).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not perform multiple queries if the first page of results has items", (done) => {
|
it("should not perform multiple queries if the first page of results has items", async () => {
|
||||||
const queryStub = sinon.stub().returns(Q.resolve(queryResultWithItemsInPage));
|
const queryStub = sinon.stub().returns(Q.resolve(queryResultWithItemsInPage));
|
||||||
QueryUtils.queryPagesUntilContentPresent(0, queryStub).finally(() => {
|
await QueryUtils.queryPagesUntilContentPresent(0, queryStub);
|
||||||
expect(queryStub.callCount).toBe(1);
|
expect(queryStub.callCount).toBe(1);
|
||||||
expect(queryStub.getCall(0).args[0]).toBe(0);
|
expect(queryStub.getCall(0).args[0]).toBe(0);
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not proceed with subsequent queries if the first one errors out", (done) => {
|
|
||||||
const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes"));
|
|
||||||
QueryUtils.queryPagesUntilContentPresent(0, queryStub).finally(() => {
|
|
||||||
expect(queryStub.callCount).toBe(1);
|
|
||||||
expect(queryStub.getCall(0).args[0]).toBe(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("queryAllPages()", () => {
|
|
||||||
const queryResultWithNoContinuation: ViewModels.QueryResults = {
|
|
||||||
documents: [{ a: "123" }],
|
|
||||||
activityId: "123",
|
|
||||||
requestCharge: 1,
|
|
||||||
hasMoreResults: false,
|
|
||||||
firstItemIndex: 1,
|
|
||||||
lastItemIndex: 1,
|
|
||||||
itemCount: 1,
|
|
||||||
};
|
|
||||||
const queryResultWithContinuation: ViewModels.QueryResults = {
|
|
||||||
documents: [{ b: "123" }],
|
|
||||||
activityId: "123",
|
|
||||||
requestCharge: 1,
|
|
||||||
hasMoreResults: true,
|
|
||||||
firstItemIndex: 0,
|
|
||||||
lastItemIndex: 0,
|
|
||||||
itemCount: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
it("should follow continuation token to fetch all pages", (done) => {
|
|
||||||
const queryStub = sinon
|
|
||||||
.stub()
|
|
||||||
.onFirstCall()
|
|
||||||
.returns(Q.resolve(queryResultWithContinuation))
|
|
||||||
.returns(Q.resolve(queryResultWithNoContinuation));
|
|
||||||
QueryUtils.queryAllPages(queryStub).then(
|
|
||||||
(results: ViewModels.QueryResults) => {
|
|
||||||
expect(queryStub.callCount).toBe(2);
|
|
||||||
expect(queryStub.getCall(0).args[0]).toBe(0);
|
|
||||||
expect(queryStub.getCall(1).args[0]).toBe(1);
|
|
||||||
expect(results.itemCount).toBe(
|
|
||||||
queryResultWithContinuation.documents.length + queryResultWithNoContinuation.documents.length
|
|
||||||
);
|
|
||||||
expect(results.requestCharge).toBe(
|
|
||||||
queryResultWithContinuation.requestCharge + queryResultWithNoContinuation.requestCharge
|
|
||||||
);
|
|
||||||
expect(results.documents).toEqual(
|
|
||||||
queryResultWithContinuation.documents.concat(queryResultWithNoContinuation.documents)
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
},
|
|
||||||
(error: any) => {
|
|
||||||
fail(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not perform subsequent fetches when result has no continuation", (done) => {
|
|
||||||
const queryStub = sinon.stub().returns(Q.resolve(queryResultWithNoContinuation));
|
|
||||||
QueryUtils.queryAllPages(queryStub).then(
|
|
||||||
(results: ViewModels.QueryResults) => {
|
|
||||||
expect(queryStub.callCount).toBe(1);
|
|
||||||
expect(queryStub.getCall(0).args[0]).toBe(0);
|
|
||||||
expect(results.itemCount).toBe(queryResultWithNoContinuation.documents.length);
|
|
||||||
expect(results.requestCharge).toBe(queryResultWithNoContinuation.requestCharge);
|
|
||||||
expect(results.documents).toEqual(queryResultWithNoContinuation.documents);
|
|
||||||
done();
|
|
||||||
},
|
|
||||||
(error: any) => {
|
|
||||||
fail(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not proceed with subsequent fetches if the first one errors out", (done) => {
|
|
||||||
const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes"));
|
|
||||||
QueryUtils.queryAllPages(queryStub).finally(() => {
|
|
||||||
expect(queryStub.callCount).toBe(1);
|
|
||||||
expect(queryStub.getCall(0).args[0]).toBe(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -81,34 +81,3 @@ export const queryPagesUntilContentPresent = async (
|
|||||||
|
|
||||||
return await doRequest(firstItemIndex);
|
return await doRequest(firstItemIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const queryAllPages = async (
|
|
||||||
queryItems: (itemIndex: number) => Promise<ViewModels.QueryResults>
|
|
||||||
): Promise<ViewModels.QueryResults> => {
|
|
||||||
const queryResults: ViewModels.QueryResults = {
|
|
||||||
documents: [],
|
|
||||||
activityId: undefined,
|
|
||||||
hasMoreResults: false,
|
|
||||||
itemCount: 0,
|
|
||||||
firstItemIndex: 0,
|
|
||||||
lastItemIndex: 0,
|
|
||||||
requestCharge: 0,
|
|
||||||
roundTrips: 0,
|
|
||||||
};
|
|
||||||
const doRequest = async (itemIndex: number): Promise<ViewModels.QueryResults> => {
|
|
||||||
const results = await queryItems(itemIndex);
|
|
||||||
const { requestCharge, hasMoreResults, itemCount, lastItemIndex, documents } = results;
|
|
||||||
queryResults.roundTrips = queryResults.roundTrips + 1;
|
|
||||||
queryResults.requestCharge = Number(queryResults.requestCharge) + Number(requestCharge);
|
|
||||||
queryResults.hasMoreResults = hasMoreResults;
|
|
||||||
queryResults.itemCount = queryResults.itemCount + itemCount;
|
|
||||||
queryResults.lastItemIndex = lastItemIndex;
|
|
||||||
queryResults.documents = queryResults.documents.concat(documents);
|
|
||||||
if (queryResults.hasMoreResults) {
|
|
||||||
return doRequest(queryResults.lastItemIndex + 1);
|
|
||||||
}
|
|
||||||
return queryResults;
|
|
||||||
};
|
|
||||||
|
|
||||||
return doRequest(0);
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user