mirror of https://gitee.com/bigwinds/arangodb
fun with custom visitors, cont.
This commit is contained in:
parent
b4ba07f765
commit
699b7e76f6
|
@ -145,12 +145,32 @@ instead.
|
||||||
vertex only if *order* was set to *preorder-expander*. Otherwise, the value of this parameter
|
vertex only if *order* was set to *preorder-expander*. Otherwise, the value of this parameter
|
||||||
will be *undefined*.
|
will be *undefined*.
|
||||||
|
|
||||||
|
The following custom visitor functions are predefined and can be used by specifying the function
|
||||||
|
name in the *visitor* attribute:
|
||||||
|
|
||||||
|
- *"_AQL::PROJECTINGVISITOR"*: this visitor will produce an object with the attributes
|
||||||
|
specified in *data.attributes* for each visited vertex. This can be used to create a
|
||||||
|
projection of each visited vertex' document.
|
||||||
|
|
||||||
|
- *"_AQL::IDVISITOR"*: this visitor will return the _id attribute of each visited vertex.
|
||||||
|
|
||||||
|
- *"_AQL::KEYVISITOR"*: this visitor will return the _key attribute of each visited vertex.
|
||||||
|
|
||||||
|
- *"_AQL::COUNTINGVISITOR"*: this visitor will return a single number indicating the number
|
||||||
|
of vertices visited.
|
||||||
|
|
||||||
|
|
||||||
- *visitorReturnsResults*: only useful in combination with a custom AQL visitor function. If
|
- *visitorReturnsResults*: only useful in combination with a custom AQL visitor function. If
|
||||||
set to *true*, the data returned by the visitor will be appended to the result. If set to
|
set to *true*, the data returned by the visitor will be appended to the result. If set to
|
||||||
*false*, any return value of the visitor function will be ignored. Instead, the visitor
|
*false*, any return value of the visitor function will be ignored. Instead, the visitor
|
||||||
function can modify its *result* parameter value in-place. At the end of the traversal,
|
function can modify its *result* parameter value in-place. At the end of the traversal,
|
||||||
*result* is expected to be an array.
|
*result* is expected to be an array.
|
||||||
|
|
||||||
|
- *data*: only useful in combination with a custom AQL visitor function. This attribute can
|
||||||
|
be used to pass arbitrary data into the custom visitor function. The value contained in the
|
||||||
|
*data* attribute will be made available to the *visitor* function in the *config.data*
|
||||||
|
attribute.
|
||||||
|
|
||||||
By default, the result of the TRAVERSAL function is an array of traversed points. Each point
|
By default, the result of the TRAVERSAL function is an array of traversed points. Each point
|
||||||
is an object consisting of the following attributes:
|
is an object consisting of the following attributes:
|
||||||
- *vertex*: The vertex at the traversal point
|
- *vertex*: The vertex at the traversal point
|
||||||
|
|
|
@ -51,6 +51,46 @@ var RegexCache = { };
|
||||||
|
|
||||||
var UserFunctions = { };
|
var UserFunctions = { };
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief prefab traversal visitors
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var DefaultVisitors = {
|
||||||
|
"_AQL::PROJECTINGVISITOR" : {
|
||||||
|
visitorReturnsResults: true,
|
||||||
|
func: function (config, result, vertex) {
|
||||||
|
var values = { };
|
||||||
|
if (typeof config.data === "object" && Array.isArray(config.data.attributes)) {
|
||||||
|
config.data.attributes.forEach(function (attribute) {
|
||||||
|
values[attribute] = vertex[attribute];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_AQL::IDVISITOR" : {
|
||||||
|
visitorReturnsResults: true,
|
||||||
|
func: function (config, result, vertex) {
|
||||||
|
return vertex._id;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_AQL::KEYVISITOR" : {
|
||||||
|
visitorReturnsResults: true,
|
||||||
|
func: function (config, result, vertex) {
|
||||||
|
return vertex._key;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_AQL::COUNTINGVISITOR" : {
|
||||||
|
visitorReturnsResults: false,
|
||||||
|
func: function (config, result) {
|
||||||
|
if (result.length === 0) {
|
||||||
|
result.push(0);
|
||||||
|
}
|
||||||
|
result[0]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief type weight used for sorting and comparing
|
/// @brief type weight used for sorting and comparing
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -194,26 +234,35 @@ function reloadUserFunctions () {
|
||||||
/// @brief get a user-function by name
|
/// @brief get a user-function by name
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function GET_USERFUNCTION (name) {
|
function GET_USERFUNCTION (name, config) {
|
||||||
var prefix = DB_PREFIX(), reloaded = false;
|
var prefix = DB_PREFIX(), reloaded = false;
|
||||||
var key = name.toUpperCase();
|
var key = name.toUpperCase();
|
||||||
|
|
||||||
if (! UserFunctions.hasOwnProperty(prefix)) {
|
var func;
|
||||||
reloadUserFunctions();
|
|
||||||
reloaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! UserFunctions[prefix].hasOwnProperty(key) && ! reloaded) {
|
if (DefaultVisitors.hasOwnProperty(key)) {
|
||||||
// last chance
|
var visitor = DefaultVisitors[key];
|
||||||
reloadUserFunctions();
|
func = visitor.func;
|
||||||
|
config.visitorReturnsResults = visitor.visitorReturnsResults;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (! UserFunctions.hasOwnProperty(prefix)) {
|
||||||
|
reloadUserFunctions();
|
||||||
|
reloaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (! UserFunctions[prefix].hasOwnProperty(key)) {
|
if (! UserFunctions[prefix].hasOwnProperty(key) && ! reloaded) {
|
||||||
THROW(null, INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, name);
|
// last chance
|
||||||
|
reloadUserFunctions();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! UserFunctions[prefix].hasOwnProperty(key)) {
|
||||||
|
THROW(null, INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
func = UserFunctions[prefix][key].func;
|
||||||
}
|
}
|
||||||
|
|
||||||
var func = UserFunctions[prefix][key].func;
|
|
||||||
|
|
||||||
if (typeof func !== "function") {
|
if (typeof func !== "function") {
|
||||||
THROW(null, INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, name);
|
THROW(null, INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, name);
|
||||||
}
|
}
|
||||||
|
@ -225,8 +274,8 @@ function GET_USERFUNCTION (name) {
|
||||||
/// @brief create a user-defined visitor from a function name
|
/// @brief create a user-defined visitor from a function name
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function GET_VISITOR (name) {
|
function GET_VISITOR (name, config) {
|
||||||
var func = GET_USERFUNCTION(name);
|
var func = GET_USERFUNCTION(name, config);
|
||||||
|
|
||||||
return function (config, result, vertex, path) {
|
return function (config, result, vertex, path) {
|
||||||
try {
|
try {
|
||||||
|
@ -250,8 +299,8 @@ function GET_VISITOR (name) {
|
||||||
/// @brief create a user-defined filter from a function name
|
/// @brief create a user-defined filter from a function name
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function GET_FILTER (name) {
|
function GET_FILTER (name, config) {
|
||||||
var func = GET_USERFUNCTION(name);
|
var func = GET_USERFUNCTION(name, config);
|
||||||
|
|
||||||
return function (config, vertex, path) {
|
return function (config, vertex, path) {
|
||||||
try {
|
try {
|
||||||
|
@ -5059,7 +5108,8 @@ function TRAVERSAL_FUNC (func,
|
||||||
endVertex : endVertex,
|
endVertex : endVertex,
|
||||||
weight : params.weight,
|
weight : params.weight,
|
||||||
defaultWeight : params.defaultWeight,
|
defaultWeight : params.defaultWeight,
|
||||||
prefill : params.prefill
|
prefill : params.prefill,
|
||||||
|
data: params.data
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof params.filter === "function") {
|
if (typeof params.filter === "function") {
|
||||||
|
@ -5456,7 +5506,7 @@ function SHORTEST_PATH_PARAMS (params) {
|
||||||
|
|
||||||
// add user-defined visitor, if specified
|
// add user-defined visitor, if specified
|
||||||
if (typeof params.visitor === "string") {
|
if (typeof params.visitor === "string") {
|
||||||
params.visitor = GET_VISITOR(params.visitor);
|
params.visitor = GET_VISITOR(params.visitor, params);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
params.visitor = TRAVERSAL_VISITOR;
|
params.visitor = TRAVERSAL_VISITOR;
|
||||||
|
@ -5464,7 +5514,7 @@ function SHORTEST_PATH_PARAMS (params) {
|
||||||
|
|
||||||
// add user-defined filter, if specified
|
// add user-defined filter, if specified
|
||||||
if (typeof params.filter === "string") {
|
if (typeof params.filter === "string") {
|
||||||
params.filter = GET_FILTER(params.filter);
|
params.filter = GET_FILTER(params.filter, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof params.distance === "string") {
|
if (typeof params.distance === "string") {
|
||||||
|
@ -5686,7 +5736,7 @@ function TRAVERSAL_PARAMS (params) {
|
||||||
|
|
||||||
// add user-defined visitor, if specified
|
// add user-defined visitor, if specified
|
||||||
if (typeof params.visitor === "string") {
|
if (typeof params.visitor === "string") {
|
||||||
params.visitor = GET_VISITOR(params.visitor);
|
params.visitor = GET_VISITOR(params.visitor, params);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
params.visitor = TRAVERSAL_VISITOR;
|
params.visitor = TRAVERSAL_VISITOR;
|
||||||
|
@ -5694,7 +5744,7 @@ function TRAVERSAL_PARAMS (params) {
|
||||||
|
|
||||||
// add user-defined filter, if specified
|
// add user-defined filter, if specified
|
||||||
if (typeof params.filter === "string") {
|
if (typeof params.filter === "string") {
|
||||||
params.filter = GET_FILTER(params.filter);
|
params.filter = GET_FILTER(params.filter, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
|
@ -6045,7 +6095,7 @@ function TRAVERSAL_TREE_PARAMS (params, connectName, func) {
|
||||||
|
|
||||||
// add user-defined visitor, if specified
|
// add user-defined visitor, if specified
|
||||||
if (typeof params.visitor === "string") {
|
if (typeof params.visitor === "string") {
|
||||||
params.visitor = GET_VISITOR(params.visitor);
|
params.visitor = GET_VISITOR(params.visitor, params);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
params.visitor = TRAVERSAL_TREE_VISITOR;
|
params.visitor = TRAVERSAL_TREE_VISITOR;
|
||||||
|
@ -6053,7 +6103,7 @@ function TRAVERSAL_TREE_PARAMS (params, connectName, func) {
|
||||||
|
|
||||||
// add user-defined filter, if specified
|
// add user-defined filter, if specified
|
||||||
if (typeof params.filter === "string") {
|
if (typeof params.filter === "string") {
|
||||||
params.filter = GET_FILTER(params.filter);
|
params.filter = GET_FILTER(params.filter, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
params.connect = AQL_TO_STRING(connectName);
|
params.connect = AQL_TO_STRING(connectName);
|
||||||
|
|
Loading…
Reference in New Issue