mirror of https://gitee.com/bigwinds/arangodb
756 lines
24 KiB
C++
756 lines
24 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
|
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// @author Heiko Kernbach
|
|
/// @author Copyright 2018, ArangoDB GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "v8-users.h"
|
|
|
|
#include "ApplicationFeatures/ApplicationServer.h"
|
|
#include "Basics/VelocyPackHelper.h"
|
|
#include "GeneralServer/AuthenticationFeature.h"
|
|
#include "Graph/Graph.h"
|
|
#include "Graph/GraphManager.h"
|
|
#include "Graph/GraphOperations.h"
|
|
#include "RestServer/DatabaseFeature.h"
|
|
#include "Transaction/V8Context.h"
|
|
#include "Utils/ExecContext.h"
|
|
#include "V8/v8-conv.h"
|
|
#include "V8/v8-globals.h"
|
|
#include "V8/v8-utils.h"
|
|
#include "V8/v8-vpack.h"
|
|
#include "V8Server/v8-externals.h"
|
|
#include "V8Server/v8-vocbase.h"
|
|
#include "V8Server/v8-vocbaseprivate.h"
|
|
#include "V8Server/v8-vocindex.h"
|
|
#include "VocBase/LogicalCollection.h"
|
|
|
|
#include <velocypack/HexDump.h>
|
|
#include <velocypack/Slice.h>
|
|
|
|
using namespace arangodb;
|
|
using namespace arangodb::velocypack;
|
|
using namespace arangodb::basics;
|
|
using namespace arangodb::graph;
|
|
using namespace arangodb::rest;
|
|
|
|
static void JS_DropGraph(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 1) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE("_drop(graphName, dropCollections)");
|
|
} else if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
bool dropCollections = false;
|
|
if (args.Length() >= 2) {
|
|
dropCollections = TRI_ObjectToBoolean(isolate, args[1]);
|
|
}
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
auto ctx = transaction::V8Context::Create(vocbase, false);
|
|
|
|
GraphManager gmngr{vocbase};
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
OperationResult result = gmngr.removeGraph(*(graph.get()), true, dropCollections);
|
|
|
|
VPackBuilder obj;
|
|
obj.add(VPackValue(VPackValueType::Object, true));
|
|
obj.add("removed", VPackValue(result.ok()));
|
|
obj.close();
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, obj.slice()));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_RenameGraphCollection(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 2) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE("_renameCollection(oldName, newName)");
|
|
} else if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
} else if (!args[1]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
std::string oldName = TRI_ObjectToString(isolate, args[0]);
|
|
std::string newName = TRI_ObjectToString(isolate, args[1]);
|
|
if (oldName.empty() || newName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
GraphManager gmngr{vocbase};
|
|
bool r = gmngr.renameGraphCollection(oldName, newName);
|
|
|
|
TRI_V8_RETURN(r);
|
|
|
|
TRI_V8_RETURN_UNDEFINED();
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_GraphExists(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 1) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE("_exists(graphName)");
|
|
} else if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
// check if graph already exists
|
|
GraphManager gmngr{vocbase};
|
|
bool r = gmngr.graphExists(graphName);
|
|
|
|
TRI_V8_RETURN(r);
|
|
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_GetGraph(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 1) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE("_graph(graphName)");
|
|
} else if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
|
|
GraphManager gmngr{vocbase};
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder result;
|
|
result.openObject();
|
|
graph.get()->graphForClient(result);
|
|
result.close();
|
|
VPackSlice resSlice = result.slice().get("graph");
|
|
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, resSlice));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_GetGraphs(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
|
|
GraphManager gmngr{vocbase};
|
|
VPackBuilder result;
|
|
OperationResult r = gmngr.readGraphs(result, arangodb::aql::PART_DEPENDENT);
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
if (!result.isEmpty()) {
|
|
auto ctx = std::make_shared<transaction::StandaloneContext>(vocbase);
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice().get("graphs"), ctx->getVPackOptionsForDump()));
|
|
}
|
|
|
|
TRI_V8_RETURN_UNDEFINED();
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_GetGraphKeys(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
|
|
GraphManager gmngr{vocbase};
|
|
VPackBuilder result;
|
|
OperationResult r = gmngr.readGraphKeys(result, arangodb::aql::PART_DEPENDENT);
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
if (!result.isEmpty()) {
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice().get("graphs")));
|
|
}
|
|
|
|
TRI_V8_RETURN_UNDEFINED();
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_CreateGraph(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
// TODO Needs to return a wrapped Graph!
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 1) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_create(graphName, edgeDefinitions, orphanCollections, options)");
|
|
} else if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
|
|
VPackBuilder builder;
|
|
builder.openObject();
|
|
|
|
builder.add("name", VPackValue(graphName));
|
|
if (args.Length() >= 2 && !args[1]->IsNullOrUndefined()) {
|
|
builder.add(VPackValue(StaticStrings::GraphEdgeDefinitions));
|
|
TRI_V8ToVPack(isolate, builder, args[1], true, true);
|
|
builder.close();
|
|
}
|
|
if (args.Length() >= 3 && !args[2]->IsNullOrUndefined()) {
|
|
builder.add(VPackValue(StaticStrings::GraphOrphans));
|
|
TRI_V8ToVPack(isolate, builder, args[2], true, true);
|
|
builder.close();
|
|
}
|
|
if (args.Length() >= 4 && !args[3]->IsNullOrUndefined()) {
|
|
builder.add(VPackValue("options"));
|
|
TRI_V8ToVPack(isolate, builder, args[3], true, true);
|
|
builder.close();
|
|
}
|
|
|
|
builder.close();
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
|
|
GraphManager gmngr{vocbase};
|
|
OperationResult r = gmngr.createGraph(builder.slice(), false);
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder result;
|
|
result.openObject();
|
|
graph.get()->graphForClient(result);
|
|
result.close();
|
|
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice()));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_AddEdgeDefinitions(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 2) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE("_extendEdgeDefinitions(edgeDefinition)");
|
|
}
|
|
if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
|
|
VPackBuilder edgeDefinition;
|
|
TRI_V8ToVPack(isolate, edgeDefinition, args[1], false);
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
GraphManager gmngr{vocbase};
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
auto ctx = transaction::V8Context::Create(vocbase, true);
|
|
GraphOperations gops{*graph.get(), vocbase, ctx};
|
|
OperationResult r = gops.addEdgeDefinition(edgeDefinition.slice(), false);
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder result;
|
|
result.openObject();
|
|
graph.get()->graphForClient(result);
|
|
result.close();
|
|
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice()));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_EditEdgeDefinitions(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 2) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE("_editEdgeDefinitions(edgeDefinition)");
|
|
}
|
|
if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
|
|
VPackBuilder edgeDefinition;
|
|
TRI_V8ToVPack(isolate, edgeDefinition, args[1], false);
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
GraphManager gmngr{vocbase};
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
auto ctx = transaction::V8Context::Create(vocbase, true);
|
|
GraphOperations gops{*graph.get(), vocbase, ctx};
|
|
OperationResult r =
|
|
gops.editEdgeDefinition(edgeDefinition.slice(), false,
|
|
edgeDefinition.slice().get("collection").copyString());
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder result;
|
|
result.openObject();
|
|
graph.get()->graphForClient(result);
|
|
result.close();
|
|
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice()));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_RemoveVertexCollection(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 2) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_removeVertexCollection(vertexName, dropCollection)");
|
|
}
|
|
if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
if (!args[1]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_removeVertexCollection(vertexName, dropCollection)");
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
std::string vertexName = TRI_ObjectToString(isolate, args[1]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
if (vertexName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_removeVertexCollection(vertexName, dropCollection)");
|
|
}
|
|
bool dropCollection = false;
|
|
if (args.Length() >= 3) {
|
|
dropCollection = TRI_ObjectToBoolean(isolate, args[2]);
|
|
}
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
GraphManager gmngr{vocbase};
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder builder;
|
|
builder.openObject();
|
|
builder.add("collection", VPackValue(vertexName));
|
|
builder.close();
|
|
|
|
auto ctx = transaction::V8Context::Create(vocbase, true);
|
|
GraphOperations gops{*graph.get(), vocbase, ctx};
|
|
OperationResult r = gops.eraseOrphanCollection(false, vertexName, dropCollection);
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder result;
|
|
result.openObject();
|
|
graph.get()->graphForClient(result);
|
|
result.close();
|
|
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice()));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_AddVertexCollection(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 2) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_addVertexCollection(vertexName, createCollection)");
|
|
}
|
|
if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
if (!args[1]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_addVertexCollection(vertexName, createCollection)");
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
std::string vertexName = TRI_ObjectToString(isolate, args[1]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
if (vertexName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_addVertexCollection(vertexName, createCollection)");
|
|
}
|
|
bool createCollection = true;
|
|
if (args.Length() >= 3) {
|
|
createCollection = TRI_ObjectToBoolean(isolate, args[2]);
|
|
}
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
auto ctx = transaction::V8Context::Create(vocbase, true);
|
|
|
|
GraphManager gmngr{vocbase};
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
GraphOperations gops{*graph.get(), vocbase, ctx};
|
|
|
|
VPackBuilder builder;
|
|
builder.openObject();
|
|
builder.add("collection", VPackValue(vertexName));
|
|
builder.close();
|
|
|
|
OperationResult r = gops.addOrphanCollection(builder.slice(), false, createCollection);
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder result;
|
|
result.openObject();
|
|
graph.get()->graphForClient(result);
|
|
result.close();
|
|
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice()));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void JS_DropEdgeDefinition(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
|
v8::HandleScope scope(isolate);
|
|
|
|
if (args.Length() < 2) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_deleteEdgeDefinition(edgeCollection, dropCollection)");
|
|
}
|
|
if (!args[0]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
if (!args[1]->IsString()) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_deleteEdgeDefinition(edgeCollection, dropCollection)");
|
|
}
|
|
std::string graphName = TRI_ObjectToString(isolate, args[0]);
|
|
std::string edgeDefinitionName = TRI_ObjectToString(isolate, args[1]);
|
|
if (graphName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_GRAPH_CREATE_MISSING_NAME);
|
|
}
|
|
if (edgeDefinitionName.empty()) {
|
|
TRI_V8_THROW_EXCEPTION_USAGE(
|
|
"_deleteEdgeDefinition(edgeCollection, dropCollection)");
|
|
}
|
|
|
|
bool dropCollections = false;
|
|
if (args.Length() >= 3) {
|
|
dropCollections = TRI_ObjectToBoolean(isolate, args[2]);
|
|
}
|
|
|
|
auto& vocbase = GetContextVocBase(isolate);
|
|
|
|
GraphManager gmngr{vocbase};
|
|
auto graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
auto ctx = transaction::V8Context::Create(vocbase, true);
|
|
GraphOperations gops{*graph.get(), vocbase, ctx};
|
|
OperationResult r = gops.eraseEdgeDefinition(false, edgeDefinitionName, dropCollections);
|
|
|
|
if (r.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(r.errorNumber(), r.errorMessage());
|
|
}
|
|
|
|
graph = gmngr.lookupGraphByName(graphName);
|
|
if (graph.fail()) {
|
|
TRI_V8_THROW_EXCEPTION_MESSAGE(graph.errorNumber(), graph.errorMessage());
|
|
}
|
|
TRI_ASSERT(graph.get() != nullptr);
|
|
|
|
VPackBuilder result;
|
|
result.openObject();
|
|
graph.get()->graphForClient(result);
|
|
result.close();
|
|
|
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, result.slice()));
|
|
TRI_V8_TRY_CATCH_END
|
|
}
|
|
|
|
static void InitV8GeneralGraphClass(v8::Handle<v8::Context> context, TRI_vocbase_t* vocbase,
|
|
TRI_v8_global_t* v8g, v8::Isolate* isolate) {
|
|
/* FULL API
|
|
* _edgeCollections
|
|
* _vertexCollections(bool excludeOrphans)
|
|
* _EDGES
|
|
* _INEDGES
|
|
* _OUTEDGES
|
|
* _edges
|
|
* _vertices
|
|
* _fromVertex(edgeId)
|
|
* _toVertex(edgeId)
|
|
* _getEdgeCollectionByName
|
|
* _getVertexCollectionByName
|
|
* _neighbors
|
|
* _commonNeighbors
|
|
* _countCommonNeighbors
|
|
* _commonProperties
|
|
* _countCommonProperties
|
|
* _paths
|
|
* _shortestPath
|
|
* _distanceTo
|
|
* _absoluteEccentricity
|
|
* _farness
|
|
* _absoluteCloseness
|
|
* _eccentricity
|
|
* _closeness
|
|
* _absoluteBetweenness
|
|
* _betweenness
|
|
* _radius
|
|
* _diameter
|
|
* _orphanCollections
|
|
* _renameVertexCollection
|
|
* _getConnectingEdges
|
|
*/
|
|
|
|
v8::Handle<v8::ObjectTemplate> rt;
|
|
v8::Handle<v8::FunctionTemplate> ft;
|
|
|
|
ft = v8::FunctionTemplate::New(isolate);
|
|
ft->SetClassName(TRI_V8_ASCII_STRING(isolate, "ArangoGraph"));
|
|
|
|
rt = ft->InstanceTemplate();
|
|
rt->SetInternalFieldCount(2);
|
|
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_addVertexCollection"),
|
|
JS_AddVertexCollection);
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_deleteEdgeDefinition"),
|
|
JS_DropEdgeDefinition);
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_editEdgeDefinitions"),
|
|
JS_EditEdgeDefinitions);
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_extendEdgeDefinitions"),
|
|
JS_AddEdgeDefinitions);
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_removeVertexCollection"),
|
|
JS_RemoveVertexCollection);
|
|
|
|
v8g->GeneralGraphTempl.Reset(isolate, rt);
|
|
ft->SetClassName(TRI_V8_ASCII_STRING(isolate, "ArangoGraphCtor"));
|
|
TRI_AddGlobalFunctionVocbase(isolate,
|
|
TRI_V8_ASCII_STRING(isolate, "ArangoGraphCtor"),
|
|
ft->GetFunction(), true);
|
|
|
|
// TODO WE DO NOT NEED THIS. Update _create to return a graph object properly
|
|
// register the global object
|
|
v8::Handle<v8::Object> aa = rt->NewInstance();
|
|
if (!aa.IsEmpty()) {
|
|
TRI_AddGlobalVariableVocbase(isolate,
|
|
TRI_V8_ASCII_STRING(isolate, "ArangoGraph"), aa);
|
|
}
|
|
}
|
|
|
|
#ifdef USE_ENTERPRISE
|
|
static void InitV8SmartGraphClass(v8::Handle<v8::Context> context, TRI_vocbase_t* vocbase,
|
|
TRI_v8_global_t* v8g, v8::Isolate* isolate) {
|
|
v8::Handle<v8::ObjectTemplate> rt;
|
|
v8::Handle<v8::FunctionTemplate> ft;
|
|
|
|
ft = v8::FunctionTemplate::New(isolate);
|
|
ft->SetClassName(TRI_V8_ASCII_STRING(isolate, "ArangoSmartGraph"));
|
|
|
|
rt = ft->InstanceTemplate();
|
|
rt->SetInternalFieldCount(2);
|
|
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_addVertexCollection"),
|
|
JS_AddVertexCollection);
|
|
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_deleteEdgeDefinition"),
|
|
JS_DropEdgeDefinition);
|
|
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_editEdgeDefinitions"),
|
|
JS_EditEdgeDefinitions);
|
|
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_extendEdgeDefinitions"),
|
|
JS_AddEdgeDefinitions);
|
|
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_removeVertexCollection"),
|
|
JS_RemoveVertexCollection);
|
|
|
|
v8g->SmartGraphTempl.Reset(isolate, rt);
|
|
ft->SetClassName(TRI_V8_ASCII_STRING(isolate, "ArangoSmartGraphCtor"));
|
|
TRI_AddGlobalFunctionVocbase(isolate,
|
|
TRI_V8_ASCII_STRING(isolate,
|
|
"ArangoSmartGraphCtor"),
|
|
ft->GetFunction(), true);
|
|
|
|
// register the global object
|
|
v8::Handle<v8::Object> aa = rt->NewInstance();
|
|
if (!aa.IsEmpty()) {
|
|
TRI_AddGlobalVariableVocbase(
|
|
isolate, TRI_V8_ASCII_STRING(isolate, "ArangoSmartGraph"), aa);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static void InitV8GeneralGraphModule(v8::Handle<v8::Context> context, TRI_vocbase_t* vocbase,
|
|
TRI_v8_global_t* v8g, v8::Isolate* isolate) {
|
|
/* These functions still have a JS only implementation
|
|
* JS ONLY:
|
|
* _edgeDefinitions
|
|
* _extendEdgeDefinitions
|
|
* _relation
|
|
* _registerCompatibilityFunctions
|
|
*/
|
|
|
|
/* TODO
|
|
* _create // SG => Potentially returns SG
|
|
* _graph // SG => Potentially returns SG
|
|
*/
|
|
v8::Handle<v8::ObjectTemplate> rt;
|
|
v8::Handle<v8::FunctionTemplate> ft;
|
|
ft = v8::FunctionTemplate::New(isolate);
|
|
ft->SetClassName(TRI_V8_ASCII_STRING(isolate, "ArangoGeneralGraphModule"));
|
|
rt = ft->InstanceTemplate();
|
|
rt->SetInternalFieldCount(0);
|
|
|
|
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "_create"), JS_CreateGraph);
|
|
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "_drop"), JS_DropGraph);
|
|
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "_exists"), JS_GraphExists);
|
|
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "_graph"), JS_GetGraph);
|
|
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "_list"), JS_GetGraphKeys);
|
|
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING(isolate, "_listObjects"), JS_GetGraphs);
|
|
TRI_AddMethodVocbase(isolate, rt,
|
|
TRI_V8_ASCII_STRING(isolate, "_renameCollection"),
|
|
JS_RenameGraphCollection);
|
|
|
|
v8g->GeneralGraphModuleTempl.Reset(isolate, rt);
|
|
ft->SetClassName(
|
|
TRI_V8_ASCII_STRING(isolate, "ArangoGeneralGraphModuleCtor"));
|
|
TRI_AddGlobalFunctionVocbase(
|
|
isolate, TRI_V8_ASCII_STRING(isolate, "ArangoGeneralGraphModuleCtor"),
|
|
ft->GetFunction(), true);
|
|
|
|
// register the global object
|
|
v8::Handle<v8::Object> aa = rt->NewInstance();
|
|
if (!aa.IsEmpty()) {
|
|
TRI_AddGlobalVariableVocbase(
|
|
isolate, TRI_V8_ASCII_STRING(isolate, "ArangoGeneralGraphModule"), aa);
|
|
}
|
|
}
|
|
|
|
void TRI_InitV8GeneralGraph(v8::Handle<v8::Context> context, TRI_vocbase_t* vocbase,
|
|
TRI_v8_global_t* v8g, v8::Isolate* isolate) {
|
|
InitV8GeneralGraphModule(context, vocbase, v8g, isolate);
|
|
InitV8GeneralGraphClass(context, vocbase, v8g, isolate);
|
|
#ifdef USE_ENTERPRISE
|
|
InitV8SmartGraphClass(context, vocbase, v8g, isolate);
|
|
#endif
|
|
}
|