@ultipa-graph/ultipa-node-sdk
Version:
NodeJS SDK for ultipa-server 4.0
203 lines • 9.74 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UltipaTransaction = exports.TransactionStatus = void 0;
const UltipaTransaction_Recorder_1 = require("./UltipaTransaction.Recorder");
const utils_1 = require("../utils");
const types_1 = require("../types");
const Transaction_Inserts_1 = require("./operations/Transaction.Inserts");
const Transaction_Deletes_1 = require("./operations/Transaction.Deletes");
const Transaction_Update_1 = require("./operations/Transaction.Update");
var InsertType = types_1.ULTIPA.InsertType;
const { v4: uuidv4 } = require("uuid");
var TransactionStatus;
(function (TransactionStatus) {
TransactionStatus[TransactionStatus["Open"] = 0] = "Open";
TransactionStatus[TransactionStatus["Closed"] = 1] = "Closed";
TransactionStatus[TransactionStatus["Committed"] = 2] = "Committed";
})(TransactionStatus = exports.TransactionStatus || (exports.TransactionStatus = {}));
class UltipaTransaction {
constructor(conn, session) {
this.recorder = new UltipaTransaction_Recorder_1.UltipaTransactionRecorder();
// store the items in this session, insert/delete/or uqls.
// txnItems : txnItem[];
this.status = TransactionStatus.Open;
this.conn = conn;
this.id = uuidv4();
this.session = session;
console.log(`Transaction ID ${this.id} Created`);
}
uql(uql, requestConfig) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed())
return;
var u = new utils_1.EasyUqlParse(uql);
if (u.hasWrite()) {
yield this.throwError("The uql contains some writing clauses, please using transaction api to update, insert or delete data.");
return;
}
if (u.isGlobal()) {
yield this.throwError("Database level operation can not executed in a transaction, such as privileges/user/graph/task operations");
return;
}
var res = yield this.conn.uql(uql, requestConfig);
if (res.status.code != types_1.ULTIPA.Code.SUCCESS) {
yield this.throwError(res.status.message);
return;
}
return res;
});
}
insertNodes(nodes) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed())
return;
return yield (0, Transaction_Inserts_1.InsertNodes)(this, nodes);
});
}
insertEdges(edges) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed())
return;
return yield (0, Transaction_Inserts_1.InsertEdges)(this, edges);
});
}
deleteNodes(filter) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed())
return;
return yield (0, Transaction_Deletes_1.deleteNodes)(this, filter);
});
}
deleteEdges(filter) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed())
return;
return yield (0, Transaction_Deletes_1.deleteEdges)(this, filter);
});
}
/**
* @param filter "age > 10"
* @param value "{time: "1999-01-01 12:12:00", age: 10}"
*/
updateNodes(filter, value) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed())
return;
return yield (0, Transaction_Update_1.UpdateNodes)(this, filter, value);
});
}
updateEdges(filter, value) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed())
return;
return yield (0, Transaction_Update_1.UpdateEdges)(this, filter, value);
});
}
rollback(msg) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`transaction ID: ${this.id} rollback`);
msg && console.log("Caused by " + msg);
if (yield this.checkCommitOrClosed())
return;
for (let op of this.recorder.logs.reverse()) {
switch (op.Op) {
case UltipaTransaction_Recorder_1.UltipaTransactionRecorderOp.New_Nodes:
let newNodeRes = yield this.conn.uql(`delete().nodes({_uuid in [${op.node_uuids.join(",")}]})`);
if (newNodeRes.status.code != types_1.ULTIPA.Code.SUCCESS) {
yield this.throwError(newNodeRes.status.message, false);
}
break;
case UltipaTransaction_Recorder_1.UltipaTransactionRecorderOp.New_Edges:
let resNewEdges = yield this.conn.uql(`delete().edges({_uuid in [${op.edge_uuids.join(",")}]})`);
if (resNewEdges.status.code != types_1.ULTIPA.Code.SUCCESS) {
yield this.throwError(resNewEdges.status.message, false);
}
break;
case UltipaTransaction_Recorder_1.UltipaTransactionRecorderOp.Delete_Nodes:
case UltipaTransaction_Recorder_1.UltipaTransactionRecorderOp.Update_Nodes:
let resDeleteUpdateNodes = yield this.conn.insertNodesBatchAuto(op.nodes, {
insertType: InsertType.INSERT_TYPE_OVERWRITE,
silent: true
});
if (resDeleteUpdateNodes.status.code != types_1.ULTIPA.Code.SUCCESS) {
yield this.throwError(resDeleteUpdateNodes.status.message, false);
}
if (!!op.edges && op.edges.length > 0) {
let resDeleteNodesRecoverEdges = yield this.conn.insertEdgesBatchAuto(op.edges, {
insertType: InsertType.INSERT_TYPE_OVERWRITE,
silent: true
});
if (resDeleteNodesRecoverEdges.status.code != types_1.ULTIPA.Code.SUCCESS) {
yield this.throwError(resDeleteNodesRecoverEdges.status.message, false);
}
}
break;
case UltipaTransaction_Recorder_1.UltipaTransactionRecorderOp.Update_Edges:
case UltipaTransaction_Recorder_1.UltipaTransactionRecorderOp.Delete_Edges:
let resDeleteEdges = yield this.conn.insertEdgesBatchAuto(op.edges, {
insertType: InsertType.INSERT_TYPE_OVERWRITE,
silent: true
});
if (resDeleteEdges.status.code != types_1.ULTIPA.Code.SUCCESS) {
yield this.throwError(resDeleteEdges.status.message, false);
}
break;
default:
yield this.throwError("Not Supported Operation found! " + JSON.stringify(op), false);
}
}
this.recorder = new UltipaTransaction_Recorder_1.UltipaTransactionRecorder();
});
}
commit() {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.checkCommitOrClosed(true))
return;
console.log(`transaction ID: ${this.id} committed`);
this.status = TransactionStatus.Committed;
yield this.close();
});
}
close() {
return __awaiter(this, void 0, void 0, function* () {
this.recorder.close();
if (yield this.checkCommitOrClosed(true))
return;
this.status = TransactionStatus.Closed;
});
}
throwError(msg, rollback = true) {
return __awaiter(this, void 0, void 0, function* () {
this.onError && this.onError(msg);
if (rollback) {
yield this.rollback(msg);
}
throw new Error(msg);
});
}
;
checkCommitOrClosed(silent = false) {
return __awaiter(this, void 0, void 0, function* () {
if (this.status == TransactionStatus.Committed) {
!silent && (yield this.throwError(`Transaction ID ${this.id} has been committed. other operation is not allowed`, false));
return true;
}
if (this.status == TransactionStatus.Closed) {
!silent && (yield this.throwError(`Transaction ID ${this.id} has been closed. other operation is not allowed`, false));
return true;
}
return false;
});
}
}
exports.UltipaTransaction = UltipaTransaction;
//# sourceMappingURL=UltipaTransaction.js.map