Skip to content

Commit 874a542

Browse files
committed
try fix objectid id's, check update count
1 parent 8fad7fa commit 874a542

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

OpenFlow/src/DatabaseConnection.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MongoClient, ObjectID, Db, Binary, InsertOneWriteOpResult, MapReduceOptions, CollectionInsertOneOptions, GridFSBucket, ChangeStream, CollectionAggregationOptions, MongoClientOptions } from "mongodb";
1+
import { MongoClient, ObjectID, Db, Binary, InsertOneWriteOpResult, MapReduceOptions, CollectionInsertOneOptions, GridFSBucket, ChangeStream, CollectionAggregationOptions, MongoClientOptions, ReplaceOneOptions } from "mongodb";
22
import { Crypt } from "./Crypt";
33
import { Config } from "./Config";
44
import { TokenUser, Base, WellknownIds, Rights, NoderedUtil, mapFunc, finalizeFunc, reduceFunc, Ace, UpdateOneMessage, UpdateManyMessage, InsertOrUpdateOneMessage, Role, Rolemember, User, Customer, WatchEventMessage } from "@openiap/openflow-api";
@@ -1518,7 +1518,9 @@ export class DatabaseConnection extends events.EventEmitter {
15181518
if (NoderedUtil.IsNullEmpty(name)) name = (q.item as any)._name;
15191519
if (NoderedUtil.IsNullEmpty(name)) name = "Unknown";
15201520
original = await this.getbyid<T>(q.item._id, q.collectionname, q.jwt, span);
1521-
if (!original) { throw Error("item not found or Access Denied"); }
1521+
if (!original) {
1522+
throw Error("item not found or Access Denied");
1523+
}
15221524
if (!DatabaseConnection.hasAuthorization(user, original, Rights.update)) {
15231525
throw new Error("Access denied, no authorization to UpdateOne " + q.item._type + " " + name + " to database");
15241526
}
@@ -1744,7 +1746,10 @@ export class DatabaseConnection extends events.EventEmitter {
17441746
if (q.query === null || q.query === undefined) {
17451747
const id: string = q.item._id;
17461748
const safeid = safeObjectID(id);
1747-
q.query = { $or: [{ _id: id }, { _id: safeObjectID(id) }] };
1749+
q.query = { _id: id };
1750+
if (safeid != null) {
1751+
q.query = { $or: [{ _id: id }, { _id: safeid }] };
1752+
}
17481753
}
17491754
let _query: Object = {};
17501755
if (DatabaseConnection.usemetadata(q.collectionname)) {
@@ -1753,11 +1758,12 @@ export class DatabaseConnection extends events.EventEmitter {
17531758
// todo: enforcer permissions when fetching _hist ?
17541759
_query = { $and: [q.query, this.getbasequery(q.jwt, "_acl", [Rights.update])] };
17551760
}
1761+
if (Config.api_bypass_perm_check) { _query = q.query; }
17561762

17571763
q.j = ((q.j as any) === 'true' || q.j === true);
17581764
if ((q.w as any) !== "majority") q.w = parseInt((q.w as any));
17591765

1760-
let options: CollectionInsertOneOptions = { writeConcern: { w: q.w, j: q.j } };
1766+
let options: ReplaceOneOptions = { writeConcern: { w: q.w, j: q.j }, upsert: false };
17611767
(options as any).WriteConcern = { w: q.w, j: q.j };
17621768
if (NoderedUtil.IsNullEmpty(this.replicat)) options = null;
17631769

@@ -1788,18 +1794,34 @@ export class DatabaseConnection extends events.EventEmitter {
17881794
}
17891795
}
17901796
if (!DatabaseConnection.usemetadata(q.collectionname)) {
1791-
const ot_end = Logger.otel.startTimer();
1792-
const mongodbspan: Span = Logger.otel.startSubSpan("mongodb.replaceOne", span);
1793-
q.opresult = await this.db.collection(q.collectionname).replaceOne(_query, q.item, options);
1794-
Logger.otel.endSpan(mongodbspan);
1795-
Logger.otel.endTimer(ot_end, DatabaseConnection.mongodb_replace, { collection: q.collectionname });
1797+
try {
1798+
const ot_end = Logger.otel.startTimer();
1799+
const mongodbspan: Span = Logger.otel.startSubSpan("mongodb.replaceOne", span);
1800+
q.opresult = await this.db.collection(q.collectionname).replaceOne(_query, q.item, options);
1801+
Logger.otel.endSpan(mongodbspan);
1802+
Logger.otel.endTimer(ot_end, DatabaseConnection.mongodb_replace, { collection: q.collectionname });
1803+
} catch (error) {
1804+
var msg: string = error.message;
1805+
if (msg.startsWith("After applying the update, the (immutable) field '_id' was found")) {
1806+
const safeid = safeObjectID(q.item._id);
1807+
q.opresult = await this.db.collection(q.collectionname).insertOne(q.item);
1808+
q.opresult.matchedCount = q.opresult.insertedCount;
1809+
await this.db.collection(q.collectionname).deleteOne({ _id: safeid });
1810+
}
1811+
}
1812+
if (q.opresult.matchedCount == 0 && (q.w != 0)) {
1813+
throw new Error("ReplaceOne failed, matched 0 documents with query {_id: '" + q.item._id + "'}");
1814+
}
17961815
} else {
17971816
const fsc = Config.db.db.collection(q.collectionname);
17981817
const ot_end = Logger.otel.startTimer();
17991818
const mongodbspan: Span = Logger.otel.startSubSpan("mongodb.replaceOne", span);
18001819
q.opresult = await fsc.updateOne(_query, { $set: { metadata: (q.item as any).metadata } });
18011820
Logger.otel.endSpan(mongodbspan);
18021821
Logger.otel.endTimer(ot_end, DatabaseConnection.mongodb_update, { collection: q.collectionname });
1822+
if (q.opresult.matchedCount == 0 && (q.w != 0)) {
1823+
throw new Error("ReplaceOne failed, matched 0 documents with query {_id: '" + q.item._id + "'}");
1824+
}
18031825
}
18041826
} else {
18051827
if ((q.item["$set"]) === undefined) { (q.item["$set"]) = {} };

0 commit comments

Comments
 (0)