mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-07-07 04:24:01 +01:00
Fixed sqldocument delete and update issue
This commit is contained in:
parent
ea21ab2580
commit
52807a9a0e
@ -88,6 +88,8 @@ export interface SubscriptionPolicies {
|
|||||||
|
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
_partitionKeyValue?: string;
|
_partitionKeyValue?: string;
|
||||||
|
_partitionKey?: string;
|
||||||
|
_attachments?: string;
|
||||||
_rid: string;
|
_rid: string;
|
||||||
_self: string;
|
_self: string;
|
||||||
_etag: string;
|
_etag: string;
|
||||||
|
@ -14,10 +14,11 @@ export interface IDocumentsTabContentState {
|
|||||||
isFilterOptionVisible: boolean;
|
isFilterOptionVisible: boolean;
|
||||||
isEditorVisible: boolean;
|
isEditorVisible: boolean;
|
||||||
documentContent: string;
|
documentContent: string;
|
||||||
|
selectedSqlDocumentContent: string;
|
||||||
documentIds: Array<DocumentId>;
|
documentIds: Array<DocumentId>;
|
||||||
documentSqlIds: Array<Resource>;
|
documentSqlIds: Array<Resource>;
|
||||||
selectedDocumentId?: DocumentId;
|
selectedDocumentId?: DocumentId;
|
||||||
selectedSqlDocumentId?: Resource;
|
selectedSqlDocumentId?: DocumentId;
|
||||||
isEditorContentEdited: boolean;
|
isEditorContentEdited: boolean;
|
||||||
isAllDocumentsVisible: boolean;
|
isAllDocumentsVisible: boolean;
|
||||||
}
|
}
|
||||||
@ -79,14 +80,15 @@ export function formatDocumentContent(row: DocumentId): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function formatSqlDocumentContent(row: Resource): string {
|
export function formatSqlDocumentContent(row: Resource): string {
|
||||||
const { id, _rid, _self, _ts, _etag, _partitionKeyValue } = row;
|
const { id, _rid, _self, _ts, _etag, _partitionKey, _attachments } = row;
|
||||||
const documentContent = JSON.stringify({
|
const documentContent = JSON.stringify({
|
||||||
id: id || "",
|
id: id || "",
|
||||||
_rid: _rid || "",
|
_rid: _rid || "",
|
||||||
_self: _self || "",
|
_self: _self || "",
|
||||||
_ts: _ts || "",
|
_ts: _ts || "",
|
||||||
_etag: _etag || "",
|
_etag: _etag || "",
|
||||||
_partitionKeyValue: _partitionKeyValue || "",
|
_attachments: _attachments || "",
|
||||||
|
_partitionKey: _partitionKey || "",
|
||||||
});
|
});
|
||||||
const formattedDocumentContent = documentContent.replace(/,/g, ",\n").replace("{", "{\n").replace("}", "\n}");
|
const formattedDocumentContent = documentContent.replace(/,/g, ",\n").replace("{", "{\n").replace("}", "\n}");
|
||||||
return formattedDocumentContent;
|
return formattedDocumentContent;
|
||||||
|
@ -27,6 +27,7 @@ import { Areas } from "../../Common/Constants";
|
|||||||
import { createDocument as createSqlDocuments } from "../../Common/dataAccess/createDocument";
|
import { createDocument as createSqlDocuments } from "../../Common/dataAccess/createDocument";
|
||||||
import { deleteDocument as deleteSqlDocument } from "../../Common/dataAccess/deleteDocument";
|
import { deleteDocument as deleteSqlDocument } from "../../Common/dataAccess/deleteDocument";
|
||||||
import { queryDocuments as querySqlDocuments } from "../../Common/dataAccess/queryDocuments";
|
import { queryDocuments as querySqlDocuments } from "../../Common/dataAccess/queryDocuments";
|
||||||
|
import { readDocument } from "../../Common/dataAccess/readDocument";
|
||||||
import { updateDocument as updateSqlDocuments } from "../../Common/dataAccess/updateDocument";
|
import { updateDocument as updateSqlDocuments } from "../../Common/dataAccess/updateDocument";
|
||||||
import { getEntityName } from "../../Common/DocumentUtility";
|
import { getEntityName } from "../../Common/DocumentUtility";
|
||||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||||
@ -78,8 +79,8 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
{
|
{
|
||||||
key: "_id",
|
key: "_id",
|
||||||
name: isPreferredApiMongoDB ? "_id" : "id",
|
name: isPreferredApiMongoDB ? "_id" : "id",
|
||||||
minWidth: 90,
|
minWidth: 50,
|
||||||
maxWidth: 140,
|
maxWidth: 100,
|
||||||
isResizable: true,
|
isResizable: true,
|
||||||
isCollapsible: true,
|
isCollapsible: true,
|
||||||
data: "string",
|
data: "string",
|
||||||
@ -96,7 +97,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
key: "column2",
|
key: "column2",
|
||||||
name: props.partitionKeyPropertyHeader,
|
name: props.partitionKeyPropertyHeader,
|
||||||
minWidth: 50,
|
minWidth: 50,
|
||||||
maxWidth: 60,
|
maxWidth: 100,
|
||||||
isResizable: true,
|
isResizable: true,
|
||||||
isCollapsible: true,
|
isCollapsible: true,
|
||||||
data: "number",
|
data: "number",
|
||||||
@ -128,6 +129,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
documentSqlIds: [],
|
documentSqlIds: [],
|
||||||
isEditorContentEdited: false,
|
isEditorContentEdited: false,
|
||||||
isAllDocumentsVisible: false,
|
isAllDocumentsVisible: false,
|
||||||
|
selectedSqlDocumentContent: this.initialDocumentContent,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +162,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
try {
|
try {
|
||||||
const sqlQuery = querySqlDocuments(this.props.collection.databaseId, this.props.collection.id(), query, options);
|
const sqlQuery = querySqlDocuments(this.props.collection.databaseId, this.props.collection.id(), query, options);
|
||||||
const querySqlDocumentsData = await sqlQuery.fetchNext();
|
const querySqlDocumentsData = await sqlQuery.fetchNext();
|
||||||
this.setState({ documentSqlIds: querySqlDocumentsData.resources.length ? querySqlDocumentsData.resources : [] });
|
this.setState({ documentSqlIds: querySqlDocumentsData.resources?.length ? querySqlDocumentsData.resources : [] });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.props.isExecutionError(true);
|
this.props.isExecutionError(true);
|
||||||
const errorMessage = getErrorMessage(error);
|
const errorMessage = getErrorMessage(error);
|
||||||
@ -243,13 +245,9 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
};
|
};
|
||||||
|
|
||||||
private handleRowContent = (row: DocumentId | Resource): void => {
|
private handleRowContent = (row: DocumentId | Resource): void => {
|
||||||
const formattedDocumentContent =
|
|
||||||
userContext.apiType === "Mongo"
|
userContext.apiType === "Mongo"
|
||||||
? formatDocumentContent(row as DocumentId)
|
? this.updateContent(row as DocumentId, formatDocumentContent(row as DocumentId))
|
||||||
: formatSqlDocumentContent(row as Resource);
|
: this.updateSqlContent(row as Resource);
|
||||||
userContext.apiType === "Mongo"
|
|
||||||
? this.updateContent(row as DocumentId, formattedDocumentContent)
|
|
||||||
: this.updateSqlContent(row as Resource, formattedDocumentContent);
|
|
||||||
this.setDefaultUpdateTabButtonVisibility();
|
this.setDefaultUpdateTabButtonVisibility();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -266,12 +264,17 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
private updateSqlContent = (row: Resource, formattedDocumentContent: string): void => {
|
private updateSqlContent = async (row: Resource): Promise<void> => {
|
||||||
|
const selectedDocumentId: DocumentId = new DocumentId(this.props as DocumentsTab, row, row._partitionKeyValue);
|
||||||
|
|
||||||
|
const content = await readDocument(this.props.collection, selectedDocumentId);
|
||||||
|
const formattedDocumentContent = formatSqlDocumentContent((content as unknown) as Resource);
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
documentContent: formattedDocumentContent,
|
documentContent: formattedDocumentContent,
|
||||||
isEditorVisible: true,
|
isEditorVisible: true,
|
||||||
selectedSqlDocumentId: row,
|
selectedSqlDocumentContent: formattedDocumentContent,
|
||||||
|
selectedSqlDocumentId: selectedDocumentId,
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.updateTabButton();
|
this.updateTabButton();
|
||||||
@ -287,26 +290,15 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
};
|
};
|
||||||
|
|
||||||
async updateSqlDocument(): Promise<void> {
|
async updateSqlDocument(): Promise<void> {
|
||||||
const { partitionKey, partitionKeyProperty, isExecutionError, isExecuting, collection } = this.props;
|
const { isExecutionError, isExecuting, collection } = this.props;
|
||||||
const { documentContent } = this.state;
|
const { documentContent, selectedSqlDocumentId } = this.state;
|
||||||
const partitionKeyArray = extractPartitionKey(
|
|
||||||
this.state.selectedSqlDocumentId,
|
|
||||||
getPartitionKeyDefinition(partitionKey, partitionKeyProperty) as PartitionKeyDefinition
|
|
||||||
);
|
|
||||||
|
|
||||||
const partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
|
||||||
const selectedDocumentId = new DocumentId(
|
|
||||||
this.props as DocumentsTab,
|
|
||||||
this.state.selectedSqlDocumentId,
|
|
||||||
partitionKeyValue
|
|
||||||
);
|
|
||||||
isExecutionError(false);
|
isExecutionError(false);
|
||||||
const startKey: number = this.getStartKey(Action.UpdateDocument);
|
const startKey: number = this.getStartKey(Action.UpdateDocument);
|
||||||
try {
|
try {
|
||||||
isExecuting(true);
|
isExecuting(true);
|
||||||
const updateSqlDocumentRes = await updateSqlDocuments(
|
const updateSqlDocumentRes = await updateSqlDocuments(
|
||||||
collection as ViewModels.Collection,
|
collection as ViewModels.Collection,
|
||||||
selectedDocumentId,
|
selectedSqlDocumentId,
|
||||||
JSON.parse(documentContent)
|
JSON.parse(documentContent)
|
||||||
);
|
);
|
||||||
if (updateSqlDocumentRes) {
|
if (updateSqlDocumentRes) {
|
||||||
@ -464,7 +456,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
|
|
||||||
private async onDeleteExisitingDocumentClick(): Promise<void> {
|
private async onDeleteExisitingDocumentClick(): Promise<void> {
|
||||||
const confirmationMessage = `Are you sure you want to delete the selected ${getEntityName()} ?`;
|
const confirmationMessage = `Are you sure you want to delete the selected ${getEntityName()} ?`;
|
||||||
const { isExecuting, collection, partitionKey, partitionKeyProperty } = this.props;
|
const { isExecuting, collection } = this.props;
|
||||||
const startKey: number = this.getStartKey(Action.DeleteDocument);
|
const startKey: number = this.getStartKey(Action.DeleteDocument);
|
||||||
this.props.collection.container.showOkCancelModalDialog(
|
this.props.collection.container.showOkCancelModalDialog(
|
||||||
confirmationMessage,
|
confirmationMessage,
|
||||||
@ -481,17 +473,8 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
);
|
);
|
||||||
this.queryDocumentsData();
|
this.queryDocumentsData();
|
||||||
} else {
|
} else {
|
||||||
const partitionKeyArray = extractPartitionKey(
|
const { selectedSqlDocumentId } = this.state;
|
||||||
this.state.selectedSqlDocumentId,
|
await deleteSqlDocument(collection as ViewModels.Collection, selectedSqlDocumentId);
|
||||||
getPartitionKeyDefinition(partitionKey, partitionKeyProperty) as PartitionKeyDefinition
|
|
||||||
);
|
|
||||||
const partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
|
||||||
const selectedDocumentId = new DocumentId(
|
|
||||||
this.props as DocumentsTab,
|
|
||||||
this.state.selectedSqlDocumentId,
|
|
||||||
partitionKeyValue
|
|
||||||
);
|
|
||||||
await deleteSqlDocument(collection as ViewModels.Collection, selectedDocumentId);
|
|
||||||
this.querySqlDocumentsData();
|
this.querySqlDocumentsData();
|
||||||
}
|
}
|
||||||
this.setTraceSuccess(Action.DeleteDocument, startKey);
|
this.setTraceSuccess(Action.DeleteDocument, startKey);
|
||||||
@ -506,11 +489,9 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onRevertExisitingDocumentClick(): void {
|
private onRevertExisitingDocumentClick(): void {
|
||||||
const { selectedDocumentId, selectedSqlDocumentId } = this.state;
|
const { selectedDocumentId, selectedSqlDocumentContent } = this.state;
|
||||||
const documentContent =
|
const documentContent =
|
||||||
userContext.apiType === "Mongo"
|
userContext.apiType === "Mongo" ? formatDocumentContent(selectedDocumentId) : selectedSqlDocumentContent;
|
||||||
? formatDocumentContent(selectedDocumentId)
|
|
||||||
: formatSqlDocumentContent(selectedSqlDocumentId);
|
|
||||||
this.setState({
|
this.setState({
|
||||||
documentContent: documentContent,
|
documentContent: documentContent,
|
||||||
});
|
});
|
||||||
@ -551,7 +532,8 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
try {
|
try {
|
||||||
const savedDocument = await createSqlDocuments(collection, document);
|
const savedDocument = await createSqlDocuments(collection, document);
|
||||||
if (savedDocument) {
|
if (savedDocument) {
|
||||||
this.handleRowContent(savedDocument as Resource);
|
const formattedDocumentContent = formatSqlDocumentContent((savedDocument as unknown) as Resource);
|
||||||
|
this.setState({ documentContent: formattedDocumentContent });
|
||||||
this.setDefaultUpdateTabButtonVisibility();
|
this.setDefaultUpdateTabButtonVisibility();
|
||||||
this.setTraceSuccess(Action.CreateDocument, startKey);
|
this.setTraceSuccess(Action.CreateDocument, startKey);
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,12 @@ describe("DocumentTabUtils", () => {
|
|||||||
fakeDocumentData._self = "testSelf";
|
fakeDocumentData._self = "testSelf";
|
||||||
fakeDocumentData._ts = "testTs";
|
fakeDocumentData._ts = "testTs";
|
||||||
fakeDocumentData._etag = "testEtag";
|
fakeDocumentData._etag = "testEtag";
|
||||||
fakeDocumentData._partitionKeyValue = "testPartitionKeyValue";
|
fakeDocumentData._attachments = "testAttachments";
|
||||||
|
fakeDocumentData._partitionKey = "testPartitionKey";
|
||||||
|
|
||||||
const formattedContent: string = DocumentTabUtils.formatSqlDocumentContent(fakeDocumentData);
|
const formattedContent: string = DocumentTabUtils.formatSqlDocumentContent(fakeDocumentData);
|
||||||
expect(formattedContent).toBe(
|
expect(formattedContent).toBe(
|
||||||
`{\n"id":"testId",\n"_rid":"testRid",\n"_self":"testSelf",\n"_ts":"testTs",\n"_etag":"testEtag",\n"_partitionKeyValue":"testPartitionKeyValue"\n}`
|
`{\n"id":"testId",\n"_rid":"testRid",\n"_self":"testSelf",\n"_ts":"testTs",\n"_etag":"testEtag",\n"_attachments":"testAttachments",\n"_partitionKey":"testPartitionKey"\n}`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -58,13 +60,14 @@ describe("DocumentTabUtils", () => {
|
|||||||
fakeDocumentData._self = undefined;
|
fakeDocumentData._self = undefined;
|
||||||
fakeDocumentData._ts = undefined;
|
fakeDocumentData._ts = undefined;
|
||||||
fakeDocumentData._etag = undefined;
|
fakeDocumentData._etag = undefined;
|
||||||
fakeDocumentData._partitionKeyValue = undefined;
|
fakeDocumentData._attachments = undefined;
|
||||||
|
fakeDocumentData._partitionKey = undefined;
|
||||||
const formattedContent: string = DocumentTabUtils.formatSqlDocumentContent(fakeDocumentData);
|
const formattedContent: string = DocumentTabUtils.formatSqlDocumentContent(fakeDocumentData);
|
||||||
expect(formattedContent).toBe(
|
expect(formattedContent).toBe(
|
||||||
`{\n"id":"",\n"_rid":"",\n"_self":"",\n"_ts":"",\n"_etag":"",\n"_partitionKeyValue":""\n}`
|
`{\n"id":"",\n"_rid":"",\n"_self":"",\n"_ts":"",\n"_etag":"",\n"_attachments":"",\n"_partitionKey":""\n}`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
describe("getPartitionKeyDefinition()", () => {
|
describe("getPartitionKeyDefinition()", () => {
|
||||||
const partitionKey = {} as PartitionKey;
|
const partitionKey = {} as PartitionKey;
|
||||||
partitionKey.kind = "Hash";
|
partitionKey.kind = "Hash";
|
||||||
@ -84,5 +87,4 @@ describe("DocumentTabUtils", () => {
|
|||||||
expect(formattedPartitionKey).toEqual({ kind: "Hash", version: 1, systemKey: true, paths: undefined });
|
expect(formattedPartitionKey).toEqual({ kind: "Hash", version: 1, systemKey: true, paths: undefined });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user