fix(elasticsearch): pass routing for document writes
This commit is contained in:
1 parent
910fde75e1
commit
299a9843f3
16 files changed
+912
-351
No files matched your search
@@ -244,6 +244,22 @@ function documentIdFromGridValue(value: MongoInputValue | undefined): string | n
|
||||
return id.trim() ? id : null;
|
||||
}
|
||||
|
||||
function documentRoutingValue(value: unknown): string | undefined {
|
||||
if (value === null || value === undefined) return undefined;
|
||||
const routing = typeof value === "string" ? value : String(value);
|
||||
const trimmed = routing.trim();
|
||||
return trimmed ? trimmed : undefined;
|
||||
}
|
||||
|
||||
function documentRoutingFromDocument(doc: JsonRecord | undefined): string | undefined {
|
||||
return documentRoutingValue(doc?._routing);
|
||||
}
|
||||
|
||||
function documentRoutingFromGridRow(row: MongoInputValue[] | undefined, columns: string[]): string | undefined {
|
||||
const routingColIdx = columns.indexOf("_routing");
|
||||
return routingColIdx >= 0 ? documentRoutingValue(row?.[routingColIdx]) : undefined;
|
||||
}
|
||||
|
||||
async function gridSave(changes: DocumentGridChanges) {
|
||||
const cols = changes.columns;
|
||||
const idColIdx = cols.indexOf("_id");
|
||||
@@ -258,30 +274,32 @@ async function gridSave(changes: DocumentGridChanges) {
|
||||
if (isEs) {
|
||||
const doc = documents.value[rowIdx];
|
||||
if (!doc) continue;
|
||||
const routing = documentRoutingFromDocument(doc);
|
||||
const updated = { ...doc };
|
||||
for (const [colIdx, newVal] of dirtyCols) {
|
||||
const col = cols[colIdx];
|
||||
if (col === "_id") continue;
|
||||
if (col === "_id" || col === "_routing") continue;
|
||||
if (newVal === null) {
|
||||
delete updated[col];
|
||||
} else {
|
||||
updated[col] = parseMongoDocumentInputValue(newVal);
|
||||
}
|
||||
}
|
||||
await api.mongoUpdateDocument(props.connectionId, props.database, props.collection, String(id), JSON.stringify(updated));
|
||||
await api.documentUpdateDocument(props.connectionId, props.database, props.collection, String(id), JSON.stringify(updated), routing);
|
||||
continue;
|
||||
}
|
||||
|
||||
const updateDoc = buildMongoUpdateDocument(dirtyCols, cols);
|
||||
if (Object.keys(updateDoc).length === 0) continue;
|
||||
await api.mongoUpdateDocument(props.connectionId, props.database, props.collection, String(id), JSON.stringify(updateDoc));
|
||||
await api.documentUpdateDocument(props.connectionId, props.database, props.collection, String(id), JSON.stringify(updateDoc));
|
||||
}
|
||||
|
||||
for (const rowIdx of changes.deletedRows) {
|
||||
const row = changes.rows[rowIdx];
|
||||
const id = row?.[idColIdx];
|
||||
if (id == null) continue;
|
||||
await api.mongoDeleteDocument(props.connectionId, props.database, props.collection, String(id));
|
||||
const routing = isEs ? documentRoutingFromDocument(documents.value[rowIdx]) : undefined;
|
||||
await api.documentDeleteDocument(props.connectionId, props.database, props.collection, String(id), routing);
|
||||
}
|
||||
|
||||
for (const newRow of changes.newRows) {
|
||||
@@ -289,13 +307,13 @@ async function gridSave(changes: DocumentGridChanges) {
|
||||
if (isEs) {
|
||||
const id = documentIdFromGridValue(newRow[idColIdx]);
|
||||
if (id) {
|
||||
await api.mongoUpdateDocument(props.connectionId, props.database, props.collection, id, JSON.stringify(doc));
|
||||
await api.documentUpdateDocument(props.connectionId, props.database, props.collection, id, JSON.stringify(doc), documentRoutingFromGridRow(newRow, cols));
|
||||
} else {
|
||||
await api.mongoInsertDocument(props.connectionId, props.database, props.collection, JSON.stringify(doc));
|
||||
await api.documentInsertDocument(props.connectionId, props.database, props.collection, JSON.stringify(doc));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
await api.mongoInsertDocument(props.connectionId, props.database, props.collection, JSON.stringify(doc));
|
||||
await api.documentInsertDocument(props.connectionId, props.database, props.collection, JSON.stringify(doc));
|
||||
}
|
||||
|
||||
await load();
|
||||
@@ -318,6 +336,20 @@ function elasticsearchPathIdPreview(id: string): string {
|
||||
return encodeURIComponent(id);
|
||||
}
|
||||
|
||||
function elasticsearchRoutingPreview(routing: string | undefined): string {
|
||||
return routing ? `?routing=${encodeURIComponent(routing)}` : "";
|
||||
}
|
||||
|
||||
function buildElasticsearchPartialUpdateDocument(changes: Map<number, MongoInputValue>, columns: string[]): Record<string, unknown> {
|
||||
const filtered = new Map<number, MongoInputValue>();
|
||||
for (const [colIdx, newVal] of changes) {
|
||||
const col = columns[colIdx];
|
||||
if (col === "_id" || col === "_routing") continue;
|
||||
filtered.set(colIdx, newVal);
|
||||
}
|
||||
return buildMongoUpdateDocument(filtered, columns);
|
||||
}
|
||||
|
||||
async function previewDocumentChanges(changes: DocumentGridChanges): Promise<string[]> {
|
||||
const { dirtyRows, deletedRows, newRows, columns, rows } = changes;
|
||||
const idColIdx = columns.indexOf("_id");
|
||||
@@ -330,8 +362,9 @@ async function previewDocumentChanges(changes: DocumentGridChanges): Promise<str
|
||||
const id = row?.[idColIdx];
|
||||
if (id == null) continue;
|
||||
if (isEs) {
|
||||
const updateDoc = buildMongoUpdateDocument(dirtyCols, columns);
|
||||
stmts.push(`POST /${coll}/_update/${elasticsearchPathIdPreview(String(id))}\n${JSON.stringify({ doc: updateDoc.$set ?? updateDoc }, null, 2)}`);
|
||||
const updateDoc = buildElasticsearchPartialUpdateDocument(dirtyCols, columns);
|
||||
const routing = documentRoutingFromGridRow(row, columns);
|
||||
stmts.push(`POST /${coll}/_update/${elasticsearchPathIdPreview(String(id))}${elasticsearchRoutingPreview(routing)}\n${JSON.stringify({ doc: updateDoc.$set ?? updateDoc }, null, 2)}`);
|
||||
} else {
|
||||
const updateDoc = buildMongoUpdateDocument(dirtyCols, columns);
|
||||
stmts.push(`db.${coll}.updateOne({_id: ${mongoIdPreview(id)}}, ${formatMongoShellLiteral(updateDoc)})`);
|
||||
@@ -343,7 +376,8 @@ async function previewDocumentChanges(changes: DocumentGridChanges): Promise<str
|
||||
const id = row?.[idColIdx];
|
||||
if (id == null) continue;
|
||||
if (isEs) {
|
||||
stmts.push(`DELETE /${coll}/_doc/${elasticsearchPathIdPreview(String(id))}`);
|
||||
const routing = documentRoutingFromGridRow(row, columns);
|
||||
stmts.push(`DELETE /${coll}/_doc/${elasticsearchPathIdPreview(String(id))}${elasticsearchRoutingPreview(routing)}`);
|
||||
} else {
|
||||
stmts.push(`db.${coll}.deleteOne({_id: ${mongoIdPreview(id)}})`);
|
||||
}
|
||||
@@ -370,6 +404,7 @@ const customSaveHandler = computed<CustomSaveHandler>(() => ({
|
||||
save: gridSave,
|
||||
preview: previewDocumentChanges,
|
||||
supportsInsert: true,
|
||||
readonlyColumns: documentStoreProvider.value.kind === "elasticsearch" ? ["_routing"] : undefined,
|
||||
}));
|
||||
|
||||
function stopDocumentLoadingTimer() {
|
||||
@@ -514,7 +549,10 @@ function startNew() {
|
||||
function startEdit() {
|
||||
const doc = selectedDoc.value;
|
||||
if (!doc) return;
|
||||
editFields.value = Object.entries(doc).map(([name, value]) => createEditNode(name, value, name === "_id", name === "_id"));
|
||||
editFields.value = Object.entries(doc).map(([name, value]) => {
|
||||
const readonlyMetadata = name === "_id" || (documentStoreProvider.value.kind === "elasticsearch" && name === "_routing");
|
||||
return createEditNode(name, value, readonlyMetadata, readonlyMetadata);
|
||||
});
|
||||
isEditing.value = true;
|
||||
isNew.value = false;
|
||||
}
|
||||
@@ -603,7 +641,7 @@ function buildObjectFromNodes(nodes: EditNode[], path: string): JsonRecord {
|
||||
|
||||
for (const field of nodes) {
|
||||
const name = field.keyName.trim();
|
||||
if (!name || (!path && name === "_id")) continue;
|
||||
if (!name || (!path && (name === "_id" || (documentStoreProvider.value.kind === "elasticsearch" && name === "_routing")))) continue;
|
||||
if (seen.has(name)) throw new Error(t("mongo.duplicateField", { field: name }));
|
||||
seen.add(name);
|
||||
doc[name] = buildValueFromNode(field, path ? `${path}.${name}` : name);
|
||||
@@ -629,7 +667,7 @@ async function saveDoc() {
|
||||
try {
|
||||
const doc = buildDocumentFromFields();
|
||||
if (isNew.value) {
|
||||
await api.mongoInsertDocument(props.connectionId, props.database, props.collection, JSON.stringify(doc));
|
||||
await api.documentInsertDocument(props.connectionId, props.database, props.collection, JSON.stringify(doc));
|
||||
} else if (selectedIdx.value !== null) {
|
||||
const current = documents.value[selectedIdx.value];
|
||||
const id = current?._id;
|
||||
@@ -637,7 +675,7 @@ async function saveDoc() {
|
||||
error.value = "No _id field";
|
||||
return;
|
||||
}
|
||||
await api.mongoUpdateDocument(props.connectionId, props.database, props.collection, String(id), JSON.stringify(doc));
|
||||
await api.documentUpdateDocument(props.connectionId, props.database, props.collection, String(id), JSON.stringify(doc), documentRoutingFromDocument(current));
|
||||
}
|
||||
isEditing.value = false;
|
||||
isNew.value = false;
|
||||
@@ -657,7 +695,7 @@ async function applyDeleteDoc(idx: number) {
|
||||
if (!id) return;
|
||||
error.value = "";
|
||||
try {
|
||||
await api.mongoDeleteDocument(props.connectionId, props.database, props.collection, String(id));
|
||||
await api.documentDeleteDocument(props.connectionId, props.database, props.collection, String(id), documentRoutingFromDocument(doc));
|
||||
if (selectedIdx.value === idx) {
|
||||
selectedIdx.value = null;
|
||||
editJson.value = "";
|
||||
|
||||
Reference in new issue
Block a user