You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by co...@apache.org on 2026/02/18 22:16:38 UTC
(tinkerpop) branch master updated: Replace Bytecode with GremlinLang in JavaScript GLV (#3307)
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/master by this push:
new b6ad7feaf2 Replace Bytecode with GremlinLang in JavaScript GLV (#3307)
b6ad7feaf2 is described below
commit b6ad7feaf2c718a201511f881bb0acde0fa573f7
Author: kirill-stepanishin <ki...@improving.com>
AuthorDate: Wed Feb 18 14:16:33 2026 -0800
Replace Bytecode with GremlinLang in JavaScript GLV (#3307)
As part of the TP4 migration, the server no longer accepts Bytecode and only processes Gremlin queries in script form. Replaces Bytecode + Translator with a new GremlinLang class.
Changes:
- New GremlinLang class that incrementally builds Gremlin query strings as steps are added
- GraphTraversalSource / GraphTraversal now accumulate into GremlinLang instead of Bytecode
- Client.submit() only accepts strings now; all queries sent as gremlin-lang language. OptionsStrategy extracted into RequestOptions (timeout, batchSize, bulkResults, etc.)
- Deleted Bytecode, Translator, BytecodeSerializer, and their tests
- Removed Bytecode serializers from both GraphSON and GraphBinary layers
---
.../gremlin-javascript/lib/driver/client.ts | 59 ++--
.../gremlin-javascript/lib/driver/connection.ts | 4 +-
.../lib/driver/driver-remote-connection.ts | 57 +--
.../lib/driver/remote-connection.ts | 18 +-
.../javascript/gremlin-javascript/lib/index.ts | 6 +-
.../lib/process/anonymous-traversal.ts | 4 +-
.../gremlin-javascript/lib/process/bytecode.ts | 124 -------
.../lib/process/graph-traversal.ts | 374 ++++++++++----------
.../gremlin-javascript/lib/process/gremlin-lang.ts | 185 ++++++++++
.../gremlin-javascript/lib/process/transaction.ts | 4 +-
.../gremlin-javascript/lib/process/translator.ts | 116 ------
.../lib/process/traversal-strategy.ts | 6 +-
.../gremlin-javascript/lib/process/traversal.ts | 26 +-
.../lib/structure/io/binary/GraphBinary.js | 3 -
.../structure/io/binary/internals/AnySerializer.js | 1 -
.../io/binary/internals/BytecodeSerializer.js | 249 -------------
.../io/binary/internals/GraphBinaryWriter.js | 35 +-
.../lib/structure/io/graph-serializer.ts | 7 -
.../lib/structure/io/type-serializers.ts | 38 --
.../gremlin-javascript/test/unit/bytecode-test.js | 58 ---
.../gremlin-javascript/test/unit/exports-test.js | 2 +-
.../test/unit/graphbinary/AnySerializer-test.js | 30 +-
.../unit/graphbinary/BytecodeSerializer-test.js | 212 -----------
.../unit/graphbinary/GraphBinaryReader-test.js | 4 +-
.../unit/graphbinary/GraphBinaryWriter-test.js | 47 +--
.../test/unit/graphbinary/MapSerializer-test.js | 28 +-
.../test/unit/gremlin-lang-test.js | 387 +++++++++++++++++++++
.../test/unit/translator-test.js | 143 --------
.../gremlin-javascript/test/unit/traversal-test.js | 127 +------
29 files changed, 870 insertions(+), 1484 deletions(-)
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.ts
index 609626f22a..59adff2102 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.ts
@@ -19,7 +19,6 @@
import * as utils from '../utils.js';
import Connection, { ConnectionOptions } from './connection.js';
-import Bytecode from '../process/bytecode.js';
import { Readable } from 'stream';
export type RequestOptions = {
@@ -28,6 +27,12 @@ export type RequestOptions = {
bindings?: any;
language?: string;
accept?: string;
+ evaluationTimeout?: number;
+ batchSize?: number;
+ userAgent?: string;
+ materializeProperties?: string;
+ bulkResults?: boolean | string;
+ params?: Record<string, any>;
};
type ClientOptions = ConnectionOptions & RequestOptions & { processor?: string };
@@ -100,13 +105,13 @@ export default class Client {
*/
/**
- * Send a request to the Gremlin Server, can send a script or bytecode steps.
- * @param {Bytecode|string} message The bytecode or script to send
+ * Send a request to the Gremlin Server.
+ * @param {string} message The script to send
* @param {Object|null} [bindings] The script bindings, if any.
* @param {RequestOptions} [requestOptions] Configuration specific to the current request.
* @returns {Promise}
*/
- submit(message: Bytecode | string, bindings: any | null, requestOptions?: RequestOptions): Promise<any> {
+ submit(message: string, bindings: any | null, requestOptions?: RequestOptions): Promise<any> {
const requestIdOverride = requestOptions && requestOptions.requestId;
if (requestIdOverride) {
delete requestOptions['requestId'];
@@ -120,32 +125,26 @@ export default class Client {
requestOptions,
);
+ args['language'] = 'gremlin-lang';
+ args['accept'] = this._connection.mimeType;
+
+ if (bindings) args['bindings'] = bindings;
+
if (this.options.session && this.options.processor === 'session') {
args['session'] = this.options.session;
+ return this._connection.submit('session', 'eval', args, requestIdOverride);
}
-
- if (message instanceof Bytecode) {
- if (this.options.session && this.options.processor === 'session') {
- return this._connection.submit('session', 'bytecode', args, requestIdOverride);
- }
- return this._connection.submit('traversal', 'bytecode', args, requestIdOverride);
- } else if (typeof message === 'string') {
- args['bindings'] = bindings;
- args['language'] = 'gremlin-groovy';
- args['accept'] = this._connection.mimeType;
- return this._connection.submit(this.options.processor || '', 'eval', args, requestIdOverride);
- }
- throw new TypeError('message must be of type Bytecode or string');
+ return this._connection.submit(this.options.processor || '', 'eval', args, requestIdOverride);
}
/**
- * Send a request to the Gremlin Server and receive a stream for the results, can send a script or bytecode steps.
- * @param {Bytecode|string} message The bytecode or script to send
+ * Send a request to the Gremlin Server and receive a stream for the results.
+ * @param {string} message The script to send
* @param {Object} [bindings] The script bindings, if any.
* @param {RequestOptions} [requestOptions] Configuration specific to the current request.
* @returns {ReadableStream}
*/
- stream(message: Bytecode | string, bindings: any, requestOptions?: RequestOptions): Readable {
+ stream(message: string, bindings: any, requestOptions?: RequestOptions): Readable {
const requestIdOverride = requestOptions && requestOptions.requestId;
if (requestIdOverride) {
delete requestOptions['requestId'];
@@ -159,22 +158,16 @@ export default class Client {
requestOptions,
);
+ args['language'] = 'gremlin-lang';
+ args['accept'] = this._connection.mimeType;
+
+ if (bindings) args['bindings'] = bindings;
+
if (this.options.session && this.options.processor === 'session') {
args['session'] = this.options.session;
+ return this._connection.stream('session', 'eval', args, requestIdOverride);
}
-
- if (message instanceof Bytecode) {
- if (this.options.session && this.options.processor === 'session') {
- return this._connection.stream('session', 'bytecode', args, requestIdOverride);
- }
- return this._connection.stream('traversal', 'bytecode', args, requestIdOverride);
- } else if (typeof message === 'string') {
- args['bindings'] = bindings;
- args['language'] = 'gremlin-groovy';
- args['accept'] = this._connection.mimeType;
- return this._connection.stream(this.options.processor || '', 'eval', args, requestIdOverride);
- }
- throw new TypeError('message must be of type Bytecode or string');
+ return this._connection.stream(this.options.processor || '', 'eval', args, requestIdOverride);
}
/**
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.ts
index 38a75b15a3..dc4c9804b9 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.ts
@@ -253,7 +253,7 @@ export default class Connection extends EventEmitter {
const request = {
requestId: rid,
- op: op || 'bytecode',
+ op: op || 'eval',
// if using op eval need to ensure processor stays unset if caller didn't set it.
processor: !processor && op !== 'eval' ? 'traversal' : processor,
args: args || {},
@@ -288,7 +288,7 @@ export default class Connection extends EventEmitter {
.then(() => {
const request = {
requestId: rid,
- op: op || 'bytecode',
+ op: op || 'eval',
// if using op eval need to ensure processor stays unset if caller didn't set it.
processor: !processor && op !== 'eval' ? 'traversal' : processor,
args: args || {},
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.ts
index f3d93deba2..5f17d6645c 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.ts
@@ -26,9 +26,8 @@ const RemoteConnection = rcModule.RemoteConnection;
const RemoteTraversal = rcModule.RemoteTraversal;
import * as utils from '../utils.js';
import Client, { RequestOptions } from './client.js';
-import Bytecode from '../process/bytecode.js';
+import GremlinLang from '../process/gremlin-lang.js';
import { ConnectionOptions } from './connection.js';
-import { OptionsStrategy } from '../process/traversal-strategy.js';
/**
* Represents the default {@link RemoteConnection} implementation.
@@ -70,31 +69,45 @@ export default class DriverRemoteConnection extends RemoteConnection {
}
/** @override */
- submit(bytecode: Bytecode) {
- const optionsStrategy = bytecode.sourceInstructions.find(
- (i) => i[0] === 'withStrategies' && i[1] instanceof OptionsStrategy,
- );
- const allowedKeys = [
- 'evaluationTimeout',
- 'scriptEvaluationTimeout',
- 'batchSize',
- 'requestId',
- 'userAgent',
- 'materializeProperties',
- ];
+ submit(gremlinLang: GremlinLang) {
+ gremlinLang.addG(this.options.traversalSource || 'g');
let requestOptions: RequestOptions | undefined = undefined;
- if (optionsStrategy !== undefined) {
+ const strategies = gremlinLang.getOptionsStrategies();
+ if (strategies.length > 0) {
requestOptions = {};
- const conf = optionsStrategy[1].configuration;
- for (const key in conf) {
- if (conf.hasOwnProperty(key) && allowedKeys.indexOf(key) > -1) {
- requestOptions[key as keyof RequestOptions] = conf[key];
+ const allowedKeys = [
+ 'evaluationTimeout',
+ 'scriptEvaluationTimeout',
+ 'batchSize',
+ 'requestId',
+ 'userAgent',
+ 'materializeProperties',
+ 'bulkResults',
+ ];
+ for (const strategy of strategies) {
+ for (const key in strategy.configuration) {
+ if (allowedKeys.indexOf(key) > -1) {
+ requestOptions[key as keyof RequestOptions] = strategy.configuration[key];
+ }
}
}
}
- return this._client.submit(bytecode, null, requestOptions).then((result) => new RemoteTraversal(result.toArray()));
+ if (!requestOptions) {
+ requestOptions = {};
+ }
+ if (!('bulkResults' in requestOptions)) {
+ requestOptions.bulkResults = true;
+ }
+
+ const params = gremlinLang.getParameters();
+ if (params.size > 0) {
+ requestOptions.params = Object.fromEntries(params);
+ }
+
+ return this._client.submit(gremlinLang.getGremlin(), null, requestOptions)
+ .then((result) => new RemoteTraversal(result.toArray()));
}
override createSession() {
@@ -113,11 +126,11 @@ export default class DriverRemoteConnection extends RemoteConnection {
}
override commit() {
- return this._client.submit(Bytecode.GraphOp.commit, null);
+ return this._client.submit('g.tx().commit()', null);
}
override rollback() {
- return this._client.submit(Bytecode.GraphOp.rollback, null);
+ return this._client.submit('g.tx().rollback()', null);
}
override close() {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.ts
index d653c4d975..396dc18c2f 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.ts
@@ -21,7 +21,7 @@
* @author Jorge Bay Gondra
*/
-import Bytecode from '../process/bytecode.js';
+import GremlinLang from '../process/gremlin-lang.js';
import { TraversalStrategy } from '../process/traversal-strategy.js';
import { Traversal, Traverser } from '../process/traversal.js';
import type { ConnectionOptions } from './connection.js';
@@ -64,11 +64,11 @@ export abstract class RemoteConnection {
}
/**
- * Submits the <code>Bytecode</code> provided and returns a <code>RemoteTraversal</code>.
- * @param {Bytecode} bytecode
+ * Submits the <code>GremlinLang</code> provided and returns a <code>RemoteTraversal</code>.
+ * @param {GremlinLang} gremlinLang
* @returns {Promise} Returns a <code>Promise</code> that resolves to a <code>RemoteTraversal</code>.
*/
- abstract submit(bytecode: Bytecode | null): Promise<RemoteTraversal>;
+ abstract submit(gremlinLang: GremlinLang): Promise<RemoteTraversal>;
/**
* Create a new <code>RemoteConnection</code> that is bound to a session using the configuration from this one.
@@ -78,13 +78,13 @@ export abstract class RemoteConnection {
abstract createSession(): RemoteConnection;
/**
- * Submits a <code>Bytecode.GraphOp.commit</code> to the server and closes the connection.
+ * Submits a commit operation to the server and closes the connection.
* @returns {Promise}
*/
abstract commit(): Promise<void>;
/**
- * Submits a <code>Bytecode.GraphOp.rollback</code> to the server and closes the connection.
+ * Submits a rollback operation to the server and closes the connection.
* @returns {Promise}
*/
abstract rollback(): Promise<void>;
@@ -104,7 +104,7 @@ export class RemoteTraversal extends Traversal {
public traversers: Traverser<any>[],
public sideEffects?: any[],
) {
- super(null, null, new Bytecode());
+ super(null, null);
}
}
@@ -114,7 +114,7 @@ export class RemoteStrategy extends TraversalStrategy {
* @param {RemoteConnection} connection
*/
constructor(public connection: RemoteConnection) {
- // gave this a fqcn that has a local "js:" prefix since this strategy isn't sent as bytecode to the server.
+ // gave this a fqcn that has a local "js:" prefix since this strategy isn't sent to the server.
// this is a sort of local-only strategy that actually executes client side. not sure if this prefix is the
// right way to name this or not, but it should have a name to identify it.
super('js:RemoteStrategy');
@@ -126,7 +126,7 @@ export class RemoteStrategy extends TraversalStrategy {
return Promise.resolve();
}
- return this.connection.submit(traversal.getBytecode()).then(function (remoteTraversal: RemoteTraversal) {
+ return this.connection.submit(traversal.getGremlinLang()).then(function (remoteTraversal: RemoteTraversal) {
traversal.sideEffects = remoteTraversal.sideEffects;
traversal.traversers = remoteTraversal.traversers;
});
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/index.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/index.ts
index acc5a1b33f..507265b02f 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/index.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/index.ts
@@ -27,8 +27,7 @@ import * as strategiesModule from './process/traversal-strategy.js';
import * as graph from './structure/graph.js';
import * as gs from './structure/io/graph-serializer.js';
import * as rc from './driver/remote-connection.js';
-import Bytecode from './process/bytecode.js';
-import Translator from './process/translator.js';
+import GremlinLang from './process/gremlin-lang.js';
import * as utils from './utils.js';
import DriverRemoteConnection from './driver/driver-remote-connection.js';
import ResponseError from './driver/response-error.js';
@@ -53,7 +52,6 @@ export const driver = {
};
export const process = {
- Bytecode,
EnumValue: t.EnumValue,
P: t.P,
TextP: t.TextP,
@@ -77,7 +75,7 @@ export const process = {
GraphTraversal: gt.GraphTraversal,
GraphTraversalSource: gt.GraphTraversalSource,
statics: gt.statics,
- Translator,
+ GremlinLang,
traversal: AnonymousTraversalSource.traversal,
AnonymousTraversalSource,
withOptions: t.withOptions,
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/anonymous-traversal.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/anonymous-traversal.ts
index e4d8972708..03551d95d7 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/anonymous-traversal.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/anonymous-traversal.ts
@@ -19,9 +19,9 @@
import { RemoteConnection, RemoteStrategy } from '../driver/remote-connection.js';
import { Graph } from '../structure/graph.js';
-import Bytecode from './bytecode.js';
import { GraphTraversalSource, GraphTraversal } from './graph-traversal.js';
import { TraversalStrategies } from './traversal-strategy.js';
+import GremlinLang from './gremlin-lang.js';
/**
* Provides a unified way to construct a <code>TraversalSource</code> from the perspective of the traversal. In this
@@ -62,7 +62,7 @@ export default class AnonymousTraversalSource {
return new this.traversalSourceClass!(
new Graph(),
traversalStrategies,
- new Bytecode(),
+ new GremlinLang(),
this.traversalSourceClass,
this.traversalClass,
);
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.ts
deleted file mode 100644
index 0df6802472..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * @author Jorge Bay Gondra
- */
-
-import { Traversal } from './traversal.js';
-
-export default class Bytecode {
- sourceInstructions: any[] = [];
- stepInstructions: any[] = [];
-
- /**
- * Creates a new instance of Bytecode
- * @param {Bytecode} [toClone]
- */
- constructor(toClone?: Bytecode) {
- if (!toClone) {
- this.sourceInstructions = [];
- this.stepInstructions = [];
- } else {
- this.sourceInstructions = [...toClone.sourceInstructions];
- this.stepInstructions = [...toClone.stepInstructions];
- }
- }
-
- /**
- * Adds a new source instructions
- * @param {String} name
- * @param {Array} values
- * @returns {Bytecode}
- */
- addSource(name: string, values: any[]): Bytecode {
- if (name === undefined) {
- throw new Error('Name is not defined');
- }
- const instruction = new Array(values.length + 1);
- instruction[0] = name;
- for (let i = 0; i < values.length; ++i) {
- instruction[i + 1] = values[i];
- }
- this.sourceInstructions.push(Bytecode._generateInstruction(name, values));
- return this;
- }
-
- /**
- * Adds a new step instructions
- * @param {String} name
- * @param {Array} values
- * @returns {Bytecode}
- */
- addStep(name: string, values?: any[]): Bytecode {
- if (name === undefined) {
- throw new Error('Name is not defined');
- }
- this.stepInstructions.push(Bytecode._generateInstruction(name, values));
- return this;
- }
-
- private static _generateInstruction(name: string, values?: any[]) {
- const length = (values ? values.length : 0) + 1;
- const instruction = new Array(length);
- instruction[0] = name;
- for (let i = 1; i < length; i++) {
- const val = values?.[i - 1];
- if (val instanceof Traversal && val.graph != null) {
- throw new Error(
- `The child traversal of ${val} was not spawned anonymously - use ` +
- 'the __ class rather than a TraversalSource to construct the child traversal',
- );
- }
- instruction[i] = val;
- }
- return instruction;
- }
-
- /**
- * Returns the JSON representation of the source and step instructions
- * @returns {String}
- */
- toString(): string {
- return JSON.stringify([this.sourceInstructions, this.stepInstructions]);
- }
-
- /**
- * Adds a new source instructions
- * @param {String} name
- * @param {Array} values
- * @returns {Bytecode}
- */
- static _createGraphOp(name: string, values: any[]): Bytecode {
- const bc = new Bytecode();
- bc.addSource(name, values);
- return bc;
- }
-
- /**
- * Gets the <code>Bytecode</code> that is meant to be sent as "graph operations" to the server.
- * @returns {{rollback: Bytecode, commit: Bytecode}}
- */
- static get GraphOp(): { rollback: Bytecode; commit: Bytecode } {
- return {
- commit: Bytecode._createGraphOp('tx', ['commit']),
- rollback: Bytecode._createGraphOp('tx', ['rollback']),
- };
- }
-}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.ts
index 359380d1ae..4d657797ce 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.ts
@@ -23,10 +23,10 @@
import { EnumValue, Traversal, cardinality, direction } from './traversal.js';
import { Transaction } from './transaction.js';
-import Bytecode from './bytecode.js';
import { TraversalStrategies, VertexProgramStrategy, OptionsStrategy } from './traversal-strategy.js';
import {Graph, Vertex} from '../structure/graph.js';
import { RemoteConnection, RemoteStrategy } from '../driver/remote-connection.js';
+import GremlinLang from './gremlin-lang.js';
/**
* Represents the primary DSL of the Gremlin traversal machine.
@@ -38,14 +38,14 @@ export class GraphTraversalSource {
* Creates a new instance of {@link GraphTraversalSource}.
* @param {Graph} graph
* @param {TraversalStrategies} traversalStrategies
- * @param {Bytecode} [bytecode]
+ * @param {GremlinLang} [gremlinLang] Optional GremlinLang instance.
* @param {Function} [graphTraversalSourceClass] Optional {@link GraphTraversalSource} constructor.
* @param {Function} [graphTraversalClass] Optional {@link GraphTraversal} constructor.
*/
constructor(
public graph: Graph,
public traversalStrategies: TraversalStrategies,
- public bytecode: Bytecode = new Bytecode(),
+ public gremlinLang: GremlinLang = new GremlinLang(),
public graphTraversalSourceClass: typeof GraphTraversalSource = GraphTraversalSource,
public graphTraversalClass: typeof GraphTraversal = GraphTraversal,
) {
@@ -118,18 +118,16 @@ export class GraphTraversalSource {
*/
with_(key: string, value: object | undefined = undefined): GraphTraversalSource {
const val = value === undefined ? true : value;
- let optionsStrategy = this.bytecode.sourceInstructions.find(
- (i) => i[0] === 'withStrategies' && i[1] instanceof OptionsStrategy,
- );
- if (optionsStrategy === undefined) {
- optionsStrategy = new OptionsStrategy({ [key]: val });
- return this.withStrategies(optionsStrategy);
+ const glStrategies = this.gremlinLang.getOptionsStrategies();
+ if (glStrategies.length === 0) {
+ return this.withStrategies(new OptionsStrategy({ [key]: val }));
}
- optionsStrategy[1].configuration[key] = val;
+ glStrategies[glStrategies.length - 1].configuration[key] = val;
+ const gl = new GremlinLang(this.gremlinLang);
return new this.graphTraversalSourceClass(
this.graph,
new TraversalStrategies(this.traversalStrategies),
- this.bytecode,
+ gl,
this.graphTraversalSourceClass,
this.graphTraversalClass,
);
@@ -149,11 +147,11 @@ export class GraphTraversalSource {
* @returns {GraphTraversalSource}
*/
withBulk(...args: any[]): GraphTraversalSource {
- const b = new Bytecode(this.bytecode).addSource('withBulk', args);
+ const gl = new GremlinLang(this.gremlinLang).addSource('withBulk', args);
return new this.graphTraversalSourceClass(
this.graph,
new TraversalStrategies(this.traversalStrategies),
- b,
+ gl,
this.graphTraversalSourceClass,
this.graphTraversalClass,
);
@@ -165,11 +163,11 @@ export class GraphTraversalSource {
* @returns {GraphTraversalSource}
*/
withPath(...args: any[]): GraphTraversalSource {
- const b = new Bytecode(this.bytecode).addSource('withPath', args);
+ const gl = new GremlinLang(this.gremlinLang).addSource('withPath', args);
return new this.graphTraversalSourceClass(
this.graph,
new TraversalStrategies(this.traversalStrategies),
- b,
+ gl,
this.graphTraversalSourceClass,
this.graphTraversalClass,
);
@@ -181,11 +179,11 @@ export class GraphTraversalSource {
* @returns {GraphTraversalSource}
*/
withSack(...args: any[]): GraphTraversalSource {
- const b = new Bytecode(this.bytecode).addSource('withSack', args);
+ const gl = new GremlinLang(this.gremlinLang).addSource('withSack', args);
return new this.graphTraversalSourceClass(
this.graph,
new TraversalStrategies(this.traversalStrategies),
- b,
+ gl,
this.graphTraversalSourceClass,
this.graphTraversalClass,
);
@@ -197,11 +195,11 @@ export class GraphTraversalSource {
* @returns {GraphTraversalSource}
*/
withSideEffect(...args: any[]): GraphTraversalSource {
- const b = new Bytecode(this.bytecode).addSource('withSideEffect', args);
+ const gl = new GremlinLang(this.gremlinLang).addSource('withSideEffect', args);
return new this.graphTraversalSourceClass(
this.graph,
new TraversalStrategies(this.traversalStrategies),
- b,
+ gl,
this.graphTraversalSourceClass,
this.graphTraversalClass,
);
@@ -213,11 +211,11 @@ export class GraphTraversalSource {
* @returns {GraphTraversalSource}
*/
withStrategies(...args: any[]): GraphTraversalSource {
- const b = new Bytecode(this.bytecode).addSource('withStrategies', args);
+ const gl = new GremlinLang(this.gremlinLang).addSource('withStrategies', args);
return new this.graphTraversalSourceClass(
this.graph,
new TraversalStrategies(this.traversalStrategies),
- b,
+ gl,
this.graphTraversalSourceClass,
this.graphTraversalClass,
);
@@ -229,11 +227,11 @@ export class GraphTraversalSource {
* @returns {GraphTraversalSource}
*/
withoutStrategies(...args: any[]): GraphTraversalSource {
- const b = new Bytecode(this.bytecode).addSource('withoutStrategies', args);
+ const gl = new GremlinLang(this.gremlinLang).addSource('withoutStrategies', args);
return new this.graphTraversalSourceClass(
this.graph,
new TraversalStrategies(this.traversalStrategies),
- b,
+ gl,
this.graphTraversalSourceClass,
this.graphTraversalClass,
);
@@ -245,8 +243,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
E(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('E', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('E', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -260,8 +258,8 @@ export class GraphTraversalSource {
args[i] = args[i].id
}
}
- const b = new Bytecode(this.bytecode).addStep('V', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('V', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -270,8 +268,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
addE(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('addE', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('addE', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -288,8 +286,8 @@ export class GraphTraversalSource {
args[0].set(direction.in, args[0].get(direction.in).id);
}
}
- const b = new Bytecode(this.bytecode).addStep('mergeE', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('mergeE', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -298,8 +296,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
addV(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('addV', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('addV', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -308,8 +306,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
mergeV(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('mergeV', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('mergeV', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -318,8 +316,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
inject(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('inject', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('inject', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -328,8 +326,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
io(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('io', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('io', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -338,8 +336,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
call(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('call', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('call', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
/**
@@ -348,8 +346,8 @@ export class GraphTraversalSource {
* @returns {GraphTraversal}
*/
union(...args: any[]): GraphTraversal {
- const b = new Bytecode(this.bytecode).addStep('union', args);
- return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), b);
+ const gl = new GremlinLang(this.gremlinLang).addStep('union', args);
+ return new this.graphTraversalClass(this.graph, new TraversalStrategies(this.traversalStrategies), gl);
}
}
@@ -357,15 +355,15 @@ export class GraphTraversalSource {
* Represents a graph traversal.
*/
export class GraphTraversal extends Traversal {
- constructor(graph: Graph | null, traversalStrategies: TraversalStrategies | null, bytecode: Bytecode) {
- super(graph, traversalStrategies, bytecode);
+ constructor(graph: Graph | null, traversalStrategies: TraversalStrategies | null, gremlinLang?: GremlinLang) {
+ super(graph, traversalStrategies, gremlinLang);
}
/**
* Copy a traversal so as to reset and re-use it.
*/
clone() {
- return new GraphTraversal(this.graph, this.traversalStrategies, this.getBytecode());
+ return new GraphTraversal(this.graph, this.traversalStrategies, new GremlinLang(this.gremlinLang));
}
/**
@@ -379,7 +377,7 @@ export class GraphTraversal extends Traversal {
args[i] = args[i].id
}
}
- this.bytecode.addStep('V', args);
+ this.gremlinLang.addStep('V', args);
return this;
}
@@ -389,7 +387,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
E(...args: any[]): this {
- this.bytecode.addStep('E', args);
+ this.gremlinLang.addStep('E', args);
return this;
}
@@ -399,7 +397,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
addE(...args: any[]): this {
- this.bytecode.addStep('addE', args);
+ this.gremlinLang.addStep('addE', args);
return this;
}
@@ -409,7 +407,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
addV(...args: any[]): this {
- this.bytecode.addStep('addV', args);
+ this.gremlinLang.addStep('addV', args);
return this;
}
@@ -419,7 +417,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
aggregate(...args: any[]): this {
- this.bytecode.addStep('aggregate', args);
+ this.gremlinLang.addStep('aggregate', args);
return this;
}
@@ -429,7 +427,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
all(...args: any[]): this {
- this.bytecode.addStep('all', args);
+ this.gremlinLang.addStep('all', args);
return this;
}
@@ -439,7 +437,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
and(...args: any[]): this {
- this.bytecode.addStep('and', args);
+ this.gremlinLang.addStep('and', args);
return this;
}
@@ -449,7 +447,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
any(...args: any[]): this {
- this.bytecode.addStep('any', args);
+ this.gremlinLang.addStep('any', args);
return this;
}
@@ -459,7 +457,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
as(...args: any[]): this {
- this.bytecode.addStep('as', args);
+ this.gremlinLang.addStep('as', args);
return this;
}
@@ -469,7 +467,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
asDate(...args: any[]): this {
- this.bytecode.addStep('asDate', args);
+ this.gremlinLang.addStep('asDate', args);
return this;
}
@@ -478,8 +476,8 @@ export class GraphTraversal extends Traversal {
* @param {...Object} args
* @returns {GraphTraversal}
*/
- asNumber(...args: any[]) {
- this.bytecode.addStep('asNumber', args);
+ asNumber(...args: any[]): this {
+ this.gremlinLang.addStep('asNumber', args);
return this;
}
@@ -489,7 +487,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
asString(...args: any[]): this {
- this.bytecode.addStep('asString', args);
+ this.gremlinLang.addStep('asString', args);
return this;
}
@@ -499,7 +497,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
barrier(...args: any[]): this {
- this.bytecode.addStep('barrier', args);
+ this.gremlinLang.addStep('barrier', args);
return this;
}
@@ -509,7 +507,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
both(...args: any[]): this {
- this.bytecode.addStep('both', args);
+ this.gremlinLang.addStep('both', args);
return this;
}
@@ -519,7 +517,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
bothE(...args: any[]): this {
- this.bytecode.addStep('bothE', args);
+ this.gremlinLang.addStep('bothE', args);
return this;
}
@@ -529,7 +527,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
bothV(...args: any[]): this {
- this.bytecode.addStep('bothV', args);
+ this.gremlinLang.addStep('bothV', args);
return this;
}
@@ -539,7 +537,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
branch(...args: any[]): this {
- this.bytecode.addStep('branch', args);
+ this.gremlinLang.addStep('branch', args);
return this;
}
@@ -549,7 +547,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
by(...args: any[]): this {
- this.bytecode.addStep('by', args);
+ this.gremlinLang.addStep('by', args);
return this;
}
@@ -559,7 +557,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
call(...args: any[]): this {
- this.bytecode.addStep('call', args);
+ this.gremlinLang.addStep('call', args);
return this;
}
/**
@@ -568,7 +566,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
cap(...args: any[]): this {
- this.bytecode.addStep('cap', args);
+ this.gremlinLang.addStep('cap', args);
return this;
}
@@ -578,7 +576,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
choose(...args: any[]): this {
- this.bytecode.addStep('choose', args);
+ this.gremlinLang.addStep('choose', args);
return this;
}
@@ -588,7 +586,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
coalesce(...args: any[]): this {
- this.bytecode.addStep('coalesce', args);
+ this.gremlinLang.addStep('coalesce', args);
return this;
}
@@ -598,7 +596,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
coin(...args: any[]): this {
- this.bytecode.addStep('coin', args);
+ this.gremlinLang.addStep('coin', args);
return this;
}
@@ -608,7 +606,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
combine(...args: any[]): this {
- this.bytecode.addStep('combine', args);
+ this.gremlinLang.addStep('combine', args);
return this;
}
@@ -618,7 +616,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
concat(...args: any[]): this {
- this.bytecode.addStep('concat', args);
+ this.gremlinLang.addStep('concat', args);
return this;
}
@@ -628,7 +626,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
conjoin(...args: any[]): this {
- this.bytecode.addStep('conjoin', args);
+ this.gremlinLang.addStep('conjoin', args);
return this;
}
@@ -638,7 +636,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
connectedComponent(...args: any[]): this {
- this.bytecode.addStep('connectedComponent', args);
+ this.gremlinLang.addStep('connectedComponent', args);
return this;
}
@@ -648,7 +646,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
constant(...args: any[]): this {
- this.bytecode.addStep('constant', args);
+ this.gremlinLang.addStep('constant', args);
return this;
}
@@ -658,7 +656,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
count(...args: any[]): this {
- this.bytecode.addStep('count', args);
+ this.gremlinLang.addStep('count', args);
return this;
}
@@ -668,7 +666,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
cyclicPath(...args: any[]): this {
- this.bytecode.addStep('cyclicPath', args);
+ this.gremlinLang.addStep('cyclicPath', args);
return this;
}
@@ -678,7 +676,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
dateAdd(...args: any[]): this {
- this.bytecode.addStep('dateAdd', args);
+ this.gremlinLang.addStep('dateAdd', args);
return this;
}
@@ -688,7 +686,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
dateDiff(...args: any[]): this {
- this.bytecode.addStep('dateDiff', args);
+ this.gremlinLang.addStep('dateDiff', args);
return this;
}
@@ -698,7 +696,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
dedup(...args: any[]): this {
- this.bytecode.addStep('dedup', args);
+ this.gremlinLang.addStep('dedup', args);
return this;
}
@@ -708,7 +706,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
difference(...args: any[]): this {
- this.bytecode.addStep('difference', args);
+ this.gremlinLang.addStep('difference', args);
return this;
}
@@ -718,7 +716,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
discard(...args: any[]): this {
- this.bytecode.addStep('discard', args);
+ this.gremlinLang.addStep('discard', args);
return this;
}
@@ -728,7 +726,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
disjunct(...args: any[]): this {
- this.bytecode.addStep('disjunct', args);
+ this.gremlinLang.addStep('disjunct', args);
return this;
}
@@ -738,7 +736,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
drop(...args: any[]): this {
- this.bytecode.addStep('drop', args);
+ this.gremlinLang.addStep('drop', args);
return this;
}
@@ -748,7 +746,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
element(...args: any[]): this {
- this.bytecode.addStep('element', args);
+ this.gremlinLang.addStep('element', args);
return this;
}
/**
@@ -757,7 +755,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
elementMap(...args: any[]): this {
- this.bytecode.addStep('elementMap', args);
+ this.gremlinLang.addStep('elementMap', args);
return this;
}
@@ -767,7 +765,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
emit(...args: any[]): this {
- this.bytecode.addStep('emit', args);
+ this.gremlinLang.addStep('emit', args);
return this;
}
@@ -777,7 +775,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
fail(...args: any[]): this {
- this.bytecode.addStep('fail', args);
+ this.gremlinLang.addStep('fail', args);
return this;
}
@@ -787,7 +785,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
filter(...args: any[]): this {
- this.bytecode.addStep('filter', args);
+ this.gremlinLang.addStep('filter', args);
return this;
}
@@ -797,7 +795,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
flatMap(...args: any[]): this {
- this.bytecode.addStep('flatMap', args);
+ this.gremlinLang.addStep('flatMap', args);
return this;
}
@@ -807,7 +805,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
fold(...args: any[]): this {
- this.bytecode.addStep('fold', args);
+ this.gremlinLang.addStep('fold', args);
return this;
}
@@ -817,7 +815,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
format(...args: any[]): this {
- this.bytecode.addStep('format', args);
+ this.gremlinLang.addStep('format', args);
return this;
}
@@ -832,7 +830,7 @@ export class GraphTraversal extends Traversal {
args[i] = args[i].id
}
}
- this.bytecode.addStep('from', args);
+ this.gremlinLang.addStep('from', args);
return this;
}
@@ -842,7 +840,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
group(...args: any[]): this {
- this.bytecode.addStep('group', args);
+ this.gremlinLang.addStep('group', args);
return this;
}
@@ -852,7 +850,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
groupCount(...args: any[]): this {
- this.bytecode.addStep('groupCount', args);
+ this.gremlinLang.addStep('groupCount', args);
return this;
}
@@ -862,7 +860,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
has(...args: any[]): this {
- this.bytecode.addStep('has', args);
+ this.gremlinLang.addStep('has', args);
return this;
}
@@ -872,7 +870,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
hasId(...args: any[]): this {
- this.bytecode.addStep('hasId', args);
+ this.gremlinLang.addStep('hasId', args);
return this;
}
@@ -882,7 +880,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
hasKey(...args: any[]): this {
- this.bytecode.addStep('hasKey', args);
+ this.gremlinLang.addStep('hasKey', args);
return this;
}
@@ -892,7 +890,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
hasLabel(...args: any[]): this {
- this.bytecode.addStep('hasLabel', args);
+ this.gremlinLang.addStep('hasLabel', args);
return this;
}
@@ -902,7 +900,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
hasNot(...args: any[]): this {
- this.bytecode.addStep('hasNot', args);
+ this.gremlinLang.addStep('hasNot', args);
return this;
}
@@ -912,7 +910,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
hasValue(...args: any[]): this {
- this.bytecode.addStep('hasValue', args);
+ this.gremlinLang.addStep('hasValue', args);
return this;
}
@@ -922,7 +920,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
id(...args: any[]): this {
- this.bytecode.addStep('id', args);
+ this.gremlinLang.addStep('id', args);
return this;
}
@@ -932,7 +930,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
identity(...args: any[]): this {
- this.bytecode.addStep('identity', args);
+ this.gremlinLang.addStep('identity', args);
return this;
}
@@ -942,7 +940,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
in_(...args: any[]): this {
- this.bytecode.addStep('in', args);
+ this.gremlinLang.addStep('in', args);
return this;
}
@@ -952,7 +950,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
inE(...args: any[]): this {
- this.bytecode.addStep('inE', args);
+ this.gremlinLang.addStep('inE', args);
return this;
}
@@ -962,7 +960,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
inV(...args: any[]): this {
- this.bytecode.addStep('inV', args);
+ this.gremlinLang.addStep('inV', args);
return this;
}
@@ -972,7 +970,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
index(...args: any[]): this {
- this.bytecode.addStep('index', args);
+ this.gremlinLang.addStep('index', args);
return this;
}
@@ -982,7 +980,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
inject(...args: any[]): this {
- this.bytecode.addStep('inject', args);
+ this.gremlinLang.addStep('inject', args);
return this;
}
@@ -992,7 +990,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
intersect(...args: any[]): this {
- this.bytecode.addStep('intersect', args);
+ this.gremlinLang.addStep('intersect', args);
return this;
}
@@ -1002,7 +1000,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
is(...args: any[]): this {
- this.bytecode.addStep('is', args);
+ this.gremlinLang.addStep('is', args);
return this;
}
@@ -1012,7 +1010,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
key(...args: any[]): this {
- this.bytecode.addStep('key', args);
+ this.gremlinLang.addStep('key', args);
return this;
}
@@ -1022,7 +1020,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
label(...args: any[]): this {
- this.bytecode.addStep('label', args);
+ this.gremlinLang.addStep('label', args);
return this;
}
@@ -1032,7 +1030,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
length(...args: any[]): this {
- this.bytecode.addStep('length', args);
+ this.gremlinLang.addStep('length', args);
return this;
}
@@ -1042,7 +1040,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
limit(...args: any[]): this {
- this.bytecode.addStep('limit', args);
+ this.gremlinLang.addStep('limit', args);
return this;
}
@@ -1052,7 +1050,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
local(...args: any[]): this {
- this.bytecode.addStep('local', args);
+ this.gremlinLang.addStep('local', args);
return this;
}
@@ -1062,7 +1060,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
loops(...args: any[]): this {
- this.bytecode.addStep('loops', args);
+ this.gremlinLang.addStep('loops', args);
return this;
}
@@ -1072,7 +1070,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
lTrim(...args: any[]): this {
- this.bytecode.addStep('lTrim', args);
+ this.gremlinLang.addStep('lTrim', args);
return this;
}
@@ -1082,7 +1080,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
map(...args: any[]): this {
- this.bytecode.addStep('map', args);
+ this.gremlinLang.addStep('map', args);
return this;
}
@@ -1092,7 +1090,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
match(...args: any[]): this {
- this.bytecode.addStep('match', args);
+ this.gremlinLang.addStep('match', args);
return this;
}
@@ -1102,7 +1100,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
math(...args: any[]): this {
- this.bytecode.addStep('math', args);
+ this.gremlinLang.addStep('math', args);
return this;
}
@@ -1112,7 +1110,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
max(...args: any[]): this {
- this.bytecode.addStep('max', args);
+ this.gremlinLang.addStep('max', args);
return this;
}
@@ -1122,7 +1120,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
mean(...args: any[]): this {
- this.bytecode.addStep('mean', args);
+ this.gremlinLang.addStep('mean', args);
return this;
}
@@ -1132,7 +1130,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
merge(...args: any[]): this {
- this.bytecode.addStep('merge', args);
+ this.gremlinLang.addStep('merge', args);
return this;
}
@@ -1143,14 +1141,14 @@ export class GraphTraversal extends Traversal {
*/
mergeE(...args: any[]): this {
if (args && args[0]) {
- if (args[0].get(direction.OUT) instanceof Vertex) {
- args[0].set(direction.OUT, args[0].get(direction.OUT).id);
+ if (args[0].get(direction.out) instanceof Vertex) {
+ args[0].set(direction.out, args[0].get(direction.out).id);
}
- if (args[0].get(direction.IN) instanceof Vertex) {
- args[0].set(direction.IN, args[0].get(direction.IN).id);
+ if (args[0].get(direction.in) instanceof Vertex) {
+ args[0].set(direction.in, args[0].get(direction.in).id);
}
}
- this.bytecode.addStep('mergeE', args);
+ this.gremlinLang.addStep('mergeE', args);
return this;
}
@@ -1160,7 +1158,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
mergeV(...args: any[]): this {
- this.bytecode.addStep('mergeV', args);
+ this.gremlinLang.addStep('mergeV', args);
return this;
}
@@ -1170,7 +1168,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
min(...args: any[]): this {
- this.bytecode.addStep('min', args);
+ this.gremlinLang.addStep('min', args);
return this;
}
@@ -1180,7 +1178,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
none(...args: any[]): this {
- this.bytecode.addStep('none', args);
+ this.gremlinLang.addStep('none', args);
return this;
}
@@ -1190,7 +1188,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
not(...args: any[]): this {
- this.bytecode.addStep('not', args);
+ this.gremlinLang.addStep('not', args);
return this;
}
@@ -1200,7 +1198,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
option(...args: any[]): this {
- this.bytecode.addStep('option', args);
+ this.gremlinLang.addStep('option', args);
return this;
}
@@ -1210,7 +1208,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
optional(...args: any[]): this {
- this.bytecode.addStep('optional', args);
+ this.gremlinLang.addStep('optional', args);
return this;
}
@@ -1220,7 +1218,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
or(...args: any[]): this {
- this.bytecode.addStep('or', args);
+ this.gremlinLang.addStep('or', args);
return this;
}
@@ -1230,7 +1228,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
order(...args: any[]): this {
- this.bytecode.addStep('order', args);
+ this.gremlinLang.addStep('order', args);
return this;
}
@@ -1240,7 +1238,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
otherV(...args: any[]): this {
- this.bytecode.addStep('otherV', args);
+ this.gremlinLang.addStep('otherV', args);
return this;
}
@@ -1250,7 +1248,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
out(...args: any[]): this {
- this.bytecode.addStep('out', args);
+ this.gremlinLang.addStep('out', args);
return this;
}
@@ -1260,7 +1258,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
outE(...args: any[]): this {
- this.bytecode.addStep('outE', args);
+ this.gremlinLang.addStep('outE', args);
return this;
}
@@ -1270,7 +1268,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
outV(...args: any[]): this {
- this.bytecode.addStep('outV', args);
+ this.gremlinLang.addStep('outV', args);
return this;
}
@@ -1280,7 +1278,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
pageRank(...args: any[]): this {
- this.bytecode.addStep('pageRank', args);
+ this.gremlinLang.addStep('pageRank', args);
return this;
}
@@ -1290,7 +1288,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
path(...args: any[]): this {
- this.bytecode.addStep('path', args);
+ this.gremlinLang.addStep('path', args);
return this;
}
@@ -1300,7 +1298,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
peerPressure(...args: any[]): this {
- this.bytecode.addStep('peerPressure', args);
+ this.gremlinLang.addStep('peerPressure', args);
return this;
}
@@ -1310,7 +1308,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
product(...args: any[]): this {
- this.bytecode.addStep('product', args);
+ this.gremlinLang.addStep('product', args);
return this;
}
@@ -1320,7 +1318,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
profile(...args: any[]): this {
- this.bytecode.addStep('profile', args);
+ this.gremlinLang.addStep('profile', args);
return this;
}
@@ -1330,7 +1328,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
program(...args: any[]): this {
- this.bytecode.addStep('program', args);
+ this.gremlinLang.addStep('program', args);
return this;
}
@@ -1340,7 +1338,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
project(...args: any[]): this {
- this.bytecode.addStep('project', args);
+ this.gremlinLang.addStep('project', args);
return this;
}
@@ -1350,7 +1348,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
properties(...args: any[]): this {
- this.bytecode.addStep('properties', args);
+ this.gremlinLang.addStep('properties', args);
return this;
}
@@ -1360,7 +1358,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
property(...args: any[]): this {
- this.bytecode.addStep('property', args);
+ this.gremlinLang.addStep('property', args);
return this;
}
@@ -1370,7 +1368,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
propertyMap(...args: any[]): this {
- this.bytecode.addStep('propertyMap', args);
+ this.gremlinLang.addStep('propertyMap', args);
return this;
}
@@ -1380,7 +1378,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
range(...args: any[]): this {
- this.bytecode.addStep('range', args);
+ this.gremlinLang.addStep('range', args);
return this;
}
@@ -1390,7 +1388,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
read(...args: any[]): this {
- this.bytecode.addStep('read', args);
+ this.gremlinLang.addStep('read', args);
return this;
}
@@ -1400,7 +1398,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
repeat(...args: any[]): this {
- this.bytecode.addStep('repeat', args);
+ this.gremlinLang.addStep('repeat', args);
return this;
}
@@ -1410,7 +1408,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
replace(...args: any[]): this {
- this.bytecode.addStep('replace', args);
+ this.gremlinLang.addStep('replace', args);
return this;
}
@@ -1420,7 +1418,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
reverse(...args: any[]): this {
- this.bytecode.addStep('reverse', args);
+ this.gremlinLang.addStep('reverse', args);
return this;
}
@@ -1430,7 +1428,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
rTrim(...args: any[]): this {
- this.bytecode.addStep('rTrim', args);
+ this.gremlinLang.addStep('rTrim', args);
return this;
}
@@ -1440,7 +1438,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
sack(...args: any[]): this {
- this.bytecode.addStep('sack', args);
+ this.gremlinLang.addStep('sack', args);
return this;
}
@@ -1450,7 +1448,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
sample(...args: any[]): this {
- this.bytecode.addStep('sample', args);
+ this.gremlinLang.addStep('sample', args);
return this;
}
@@ -1460,7 +1458,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
select(...args: any[]): this {
- this.bytecode.addStep('select', args);
+ this.gremlinLang.addStep('select', args);
return this;
}
@@ -1470,7 +1468,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
shortestPath(...args: any[]): this {
- this.bytecode.addStep('shortestPath', args);
+ this.gremlinLang.addStep('shortestPath', args);
return this;
}
@@ -1480,7 +1478,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
sideEffect(...args: any[]): this {
- this.bytecode.addStep('sideEffect', args);
+ this.gremlinLang.addStep('sideEffect', args);
return this;
}
@@ -1490,7 +1488,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
simplePath(...args: any[]): this {
- this.bytecode.addStep('simplePath', args);
+ this.gremlinLang.addStep('simplePath', args);
return this;
}
@@ -1500,7 +1498,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
skip(...args: any[]): this {
- this.bytecode.addStep('skip', args);
+ this.gremlinLang.addStep('skip', args);
return this;
}
@@ -1510,7 +1508,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
split(...args: any[]): this {
- this.bytecode.addStep('split', args);
+ this.gremlinLang.addStep('split', args);
return this;
}
@@ -1520,7 +1518,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
subgraph(...args: any[]): this {
- this.bytecode.addStep('subgraph', args);
+ this.gremlinLang.addStep('subgraph', args);
return this;
}
@@ -1530,7 +1528,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
substring(...args: any[]): this {
- this.bytecode.addStep('substring', args);
+ this.gremlinLang.addStep('substring', args);
return this;
}
@@ -1540,7 +1538,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
sum(...args: any[]): this {
- this.bytecode.addStep('sum', args);
+ this.gremlinLang.addStep('sum', args);
return this;
}
@@ -1550,7 +1548,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
tail(...args: any[]): this {
- this.bytecode.addStep('tail', args);
+ this.gremlinLang.addStep('tail', args);
return this;
}
@@ -1560,7 +1558,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
timeLimit(...args: any[]): this {
- this.bytecode.addStep('timeLimit', args);
+ this.gremlinLang.addStep('timeLimit', args);
return this;
}
@@ -1570,7 +1568,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
times(...args: any[]): this {
- this.bytecode.addStep('times', args);
+ this.gremlinLang.addStep('times', args);
return this;
}
@@ -1585,7 +1583,7 @@ export class GraphTraversal extends Traversal {
args[i] = args[i].id
}
}
- this.bytecode.addStep('to', args);
+ this.gremlinLang.addStep('to', args);
return this;
}
@@ -1595,7 +1593,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
toE(...args: any[]): this {
- this.bytecode.addStep('toE', args);
+ this.gremlinLang.addStep('toE', args);
return this;
}
@@ -1605,7 +1603,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
toLower(...args: any[]): this {
- this.bytecode.addStep('toLower', args);
+ this.gremlinLang.addStep('toLower', args);
return this;
}
@@ -1615,7 +1613,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
toUpper(...args: any[]): this {
- this.bytecode.addStep('toUpper', args);
+ this.gremlinLang.addStep('toUpper', args);
return this;
}
@@ -1625,7 +1623,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
toV(...args: any[]): this {
- this.bytecode.addStep('toV', args);
+ this.gremlinLang.addStep('toV', args);
return this;
}
@@ -1635,7 +1633,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
tree(...args: any[]): this {
- this.bytecode.addStep('tree', args);
+ this.gremlinLang.addStep('tree', args);
return this;
}
@@ -1645,7 +1643,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
trim(...args: any[]): this {
- this.bytecode.addStep('trim', args);
+ this.gremlinLang.addStep('trim', args);
return this;
}
@@ -1655,7 +1653,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
unfold(...args: any[]): this {
- this.bytecode.addStep('unfold', args);
+ this.gremlinLang.addStep('unfold', args);
return this;
}
@@ -1665,7 +1663,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
union(...args: any[]): this {
- this.bytecode.addStep('union', args);
+ this.gremlinLang.addStep('union', args);
return this;
}
@@ -1675,7 +1673,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
until(...args: any[]): this {
- this.bytecode.addStep('until', args);
+ this.gremlinLang.addStep('until', args);
return this;
}
@@ -1685,7 +1683,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
value(...args: any[]): this {
- this.bytecode.addStep('value', args);
+ this.gremlinLang.addStep('value', args);
return this;
}
@@ -1695,7 +1693,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
valueMap(...args: any[]): this {
- this.bytecode.addStep('valueMap', args);
+ this.gremlinLang.addStep('valueMap', args);
return this;
}
@@ -1705,7 +1703,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
values(...args: any[]): this {
- this.bytecode.addStep('values', args);
+ this.gremlinLang.addStep('values', args);
return this;
}
@@ -1715,7 +1713,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
where(...args: any[]): this {
- this.bytecode.addStep('where', args);
+ this.gremlinLang.addStep('where', args);
return this;
}
@@ -1725,7 +1723,7 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
with_(...args: any[]): this {
- this.bytecode.addStep('with', args);
+ this.gremlinLang.addStep('with', args);
return this;
}
@@ -1735,12 +1733,12 @@ export class GraphTraversal extends Traversal {
* @returns {GraphTraversal}
*/
write(...args: any[]): this {
- this.bytecode.addStep('write', args);
+ this.gremlinLang.addStep('write', args);
return this;
}
}
-export class CardinalityValue extends Bytecode {
+export class CardinalityValue extends GremlinLang {
/**
* Creates a new instance of {@link CardinalityValue}.
* @param {String} card
@@ -1780,7 +1778,7 @@ export class CardinalityValue extends Bytecode {
}
function callOnEmptyTraversal(fnName: string, args: any[]) {
- const g = new GraphTraversal(null, null, new Bytecode());
+ const g = new GraphTraversal(null, null);
return g[fnName as keyof typeof g].apply(g, args);
}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/gremlin-lang.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/gremlin-lang.ts
new file mode 100644
index 0000000000..da8483f1f5
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/gremlin-lang.ts
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import { P, TextP, EnumValue } from './traversal.js';
+import { OptionsStrategy, TraversalStrategy } from './traversal-strategy.js';
+import { Long } from '../utils.js';
+import { Vertex } from '../structure/graph.js';
+
+export default class GremlinLang {
+ private gremlin: string = '';
+ private optionsStrategies: OptionsStrategy[] = [];
+ private parameters: Map<string, any> = new Map();
+
+ constructor(toClone?: GremlinLang) {
+ if (toClone) {
+ this.gremlin = toClone.gremlin;
+ this.optionsStrategies = [...toClone.optionsStrategies];
+ this.parameters = new Map(toClone.parameters);
+ }
+ }
+
+ getOptionsStrategies(): OptionsStrategy[] {
+ return this.optionsStrategies;
+ }
+
+ addG(g: string): void {
+ this.parameters.set('g', g);
+ }
+
+ getParameters(): Map<string, any> {
+ return this.parameters;
+ }
+
+ private _predicateAsString(p: P | TextP): string {
+ if (p.operator === 'and' || p.operator === 'or') {
+ return `${this._predicateAsString(p.value)}.${p.operator}(${this._predicateAsString(p.other)})`;
+ }
+
+ let result = p.operator + '(';
+ if (Array.isArray(p.value)) {
+ result += '[' + p.value.map(v => this._argAsString(v)).join(',') + ']';
+ } else {
+ result += this._argAsString(p.value);
+ if (p.other !== undefined && p.other !== null) {
+ result += ',' + this._argAsString(p.other);
+ }
+ }
+ result += ')';
+ return result;
+ }
+
+ private _argAsString(arg: any): string {
+ if (arg === null || arg === undefined) return 'null';
+ if (typeof arg === 'boolean') return arg ? 'true' : 'false';
+ if (arg instanceof Long) {
+ return String(arg.value) + 'L';
+ }
+ if (arg instanceof Date) {
+ const iso = arg.toISOString();
+ return `datetime("${iso}")`;
+ }
+ if (typeof arg === 'number') {
+ if (Number.isNaN(arg)) return 'NaN';
+ if (arg === Infinity) return '+Infinity';
+ if (arg === -Infinity) return '-Infinity';
+ return String(arg);
+ }
+ if (typeof arg === 'string') {
+ // JSON.stringify handles all special character escaping in one call.
+ // Strip the outer double quotes and re-wrap in single quotes for Gremlin.
+ const escaped = JSON.stringify(arg).slice(1, -1).replace(/'/g, "\\'");
+ return `'${escaped}'`;
+ }
+ if (arg instanceof P || arg instanceof TextP) {
+ return this._predicateAsString(arg);
+ }
+ if (arg instanceof EnumValue) {
+ return arg.toString();
+ }
+ if (arg instanceof TraversalStrategy && !(arg instanceof OptionsStrategy)) {
+ const simpleName = arg.fqcn.split('.').pop() || arg.fqcn;
+ const configEntries = Object.entries(arg.configuration);
+ if (configEntries.length === 0) {
+ return simpleName;
+ }
+ const configStr = configEntries.map(([k, v]) => `${k}:${this._argAsString(v)}`).join(',');
+ return `new ${simpleName}(${configStr})`;
+ }
+ if (typeof arg === 'function' && arg.prototype instanceof TraversalStrategy) {
+ return arg.name;
+ }
+ if (arg instanceof Vertex) {
+ return this._argAsString(arg.id);
+ }
+ if (arg instanceof GremlinLang) {
+ return arg.getGremlin('__');
+ }
+ if (typeof arg.getGremlinLang === 'function') {
+ // This is a Traversal - render as anonymous traversal
+ if (arg.graph != null) {
+ throw new Error('Child traversal must be anonymous - use __ not g');
+ }
+ return arg.getGremlinLang().getGremlin('__');
+ }
+ if (arg instanceof Set) {
+ const items = [...arg];
+ if (items.length === 0) return '{}';
+ return '{' + items.map(a => this._argAsString(a)).join(',') + '}';
+ }
+ if (arg instanceof Map) {
+ if (arg.size === 0) return '[:]';
+ const entries: string[] = [];
+ arg.forEach((v, k) => {
+ const ks = this._argAsString(k);
+ const vs = this._argAsString(v);
+ entries.push(typeof k === 'string' ? `${ks}:${vs}` : `(${ks}):${vs}`);
+ });
+ return '[' + entries.join(',') + ']';
+ }
+ if (Array.isArray(arg)) {
+ return '[' + arg.map(a => this._argAsString(a)).join(',') + ']';
+ }
+ if (typeof arg === 'object' && arg.constructor === Object) {
+ const entries = Object.entries(arg);
+ if (entries.length === 0) return '[:]';
+ return '[' + entries.map(([k, v]) => `${this._argAsString(k)}:${this._argAsString(v)}`).join(',') + ']';
+ }
+ return String(arg);
+ }
+
+ addStep(name: string, args?: any[]): GremlinLang {
+ const argsStr = args?.length ? args.map(a => this._argAsString(a)).join(',') : '';
+ this.gremlin += `.${name}(${argsStr})`;
+ return this;
+ }
+
+ addSource(name: string, args?: any[]): GremlinLang {
+ if (name === 'CardinalityValueTraversal' && args) {
+ const card = args[0] as EnumValue;
+ this.gremlin += `Cardinality.${card.elementName}(${this._argAsString(args[1])})`;
+ return this;
+ }
+ if (name === 'withStrategies' && args) {
+ const nonOptionsStrategies: any[] = [];
+ for (const strategy of args) {
+ if (strategy instanceof OptionsStrategy) {
+ this.optionsStrategies.push(strategy);
+ } else {
+ nonOptionsStrategies.push(strategy);
+ }
+ }
+ if (nonOptionsStrategies.length > 0) {
+ const argsStr = nonOptionsStrategies.map(a => this._argAsString(a)).join(',');
+ this.gremlin += `.withStrategies(${argsStr})`;
+ }
+ return this;
+ }
+ const argsStr = args?.length ? args.map(a => this._argAsString(a)).join(',') : '';
+ this.gremlin += `.${name}(${argsStr})`;
+ return this;
+ }
+
+ getGremlin(prefix: string = 'g'): string {
+ if (this.gremlin.length > 0 && this.gremlin[0] !== '.') {
+ return this.gremlin;
+ }
+ return prefix + this.gremlin;
+ }
+}
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/transaction.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/transaction.ts
index 55b6310f9b..ad1fefe9d1 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/transaction.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/transaction.ts
@@ -18,7 +18,7 @@
*/
import { RemoteConnection, RemoteStrategy } from '../driver/remote-connection.js';
-import Bytecode from './bytecode.js';
+import GremlinLang from './gremlin-lang.js';
import { GraphTraversalSource } from './graph-traversal.js';
import { TraversalStrategies } from './traversal-strategy.js';
@@ -48,7 +48,7 @@ export class Transaction {
return new this.g.graphTraversalSourceClass(
this.g.graph,
traversalStrategy,
- new Bytecode(this.g.bytecode),
+ new GremlinLang(this.g.gremlinLang),
this.g.graphTraversalSourceClass,
this.g.graphTraversalClass,
);
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.ts
deleted file mode 100644
index fe9787006f..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/translator.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import { Traversal } from './traversal.js';
-import Bytecode from './bytecode.js';
-
-/**
- * Class to translate glv bytecode steps into executable Gremlin-Groovy script
- */
-export default class Translator {
- constructor(private traversalSource: string) {}
-
- getTraversalSource() {
- return this.traversalSource;
- }
-
- getTargetLanguage() {
- return 'gremlin-groovy';
- }
-
- of(traversalSource: string) {
- this.traversalSource = traversalSource;
- }
-
- /**
- * Returns a script representation of the given bytecode instructions.
- * @param {Object} bytecodeOrTraversal The traversal or bytecode of a traversal containing step instructions.
- * @param {boolean} child Determines if a traversal object should be treated as an anonymous child or if it is a spawn from "g"
- * @returns {string} Gremlin-Groovy script
- */
- translate(bytecodeOrTraversal: Traversal | Bytecode, child: boolean = false): string {
- let script = child ? '__' : this.traversalSource;
- const bc = bytecodeOrTraversal instanceof Bytecode ? bytecodeOrTraversal : bytecodeOrTraversal.getBytecode();
-
- const instructions = bc.stepInstructions;
-
- // build the script from the glv instructions.
- for (let i = 0; i < instructions.length; i++) {
- const params = instructions[i].slice(1);
- script += '.' + instructions[i][0] + '(';
-
- if (params.length) {
- for (let k = 0; k < params.length; k++) {
- if (k > 0) {
- script += ', ';
- }
-
- script += this.convert(params[k]);
- }
- }
-
- script += ')';
- }
-
- return script;
- }
-
- /**
- * Converts an object to a Gremlin script representation.
- * @param {Object} anyObject The object to convert to a script representation
- * @returns {string} The Gremlin script representation
- */
- convert(anyObject: any): string {
- let script = '';
- if (Object(anyObject) === anyObject) {
- if (anyObject instanceof Traversal) {
- script += this.translate(anyObject.getBytecode(), true);
- } else if (anyObject.toString() === '[object Object]') {
- Object.keys(anyObject).forEach(function (key, index) {
- if (index > 0) {
- script += ', ';
- }
- script += `('${key}', `;
- if (anyObject[key] instanceof String || typeof anyObject[key] === 'string') {
- script += `'${`${anyObject[key]}`.replaceAll("'", "\\'")}'`; // eslint-disable-line quotes
- } else {
- script += anyObject[key];
- }
- script += ')';
- });
- } else if (Array.isArray(anyObject)) {
- const parts = [];
- for (const item of anyObject) {
- parts.push(this.convert(item));
- }
- script += '[' + parts.join(', ') + ']';
- } else {
- script += anyObject.toString();
- }
- } else if (anyObject === undefined || anyObject === null) {
- script += 'null';
- } else if (typeof anyObject === 'number' || typeof anyObject === 'boolean') {
- script += anyObject;
- } else {
- script += `'${`${anyObject}`.replaceAll("'", "\\'")}'`; // eslint-disable-line quotes
- }
-
- return script;
- }
-}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.ts
index 1d03803fa0..729a6f6525 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.ts
@@ -157,13 +157,13 @@ export class SubgraphStrategy extends TraversalStrategy {
constructor(options: TraversalStrategyConfiguration) {
super('org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy', options);
if (this.configuration.vertices instanceof Traversal) {
- this.configuration.vertices = this.configuration.vertices.bytecode;
+ this.configuration.vertices = this.configuration.vertices.gremlinLang;
}
if (this.configuration.edges instanceof Traversal) {
- this.configuration.edges = this.configuration.edges.bytecode;
+ this.configuration.edges = this.configuration.edges.gremlinLang;
}
if (this.configuration.vertexProperties instanceof Traversal) {
- this.configuration.vertexProperties = this.configuration.vertexProperties.bytecode;
+ this.configuration.vertexProperties = this.configuration.vertexProperties.gremlinLang;
}
}
}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.ts
index 5ab11721d0..9f9e04c042 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.ts
@@ -22,8 +22,8 @@
*/
import { Graph } from '../structure/graph.js';
-import Bytecode from './bytecode.js';
import { TraversalStrategies } from './traversal-strategy.js';
+import GremlinLang from './gremlin-lang.js';
const itemDone = Object.freeze({ value: null, done: true });
const asyncIteratorSymbol = Symbol.asyncIterator || Symbol('@@asyncIterator');
@@ -37,7 +37,7 @@ export class Traversal {
constructor(
public graph: Graph | null,
public traversalStrategies: TraversalStrategies | null,
- public bytecode: Bytecode,
+ public gremlinLang: GremlinLang = new GremlinLang(),
) {}
/**
@@ -47,9 +47,9 @@ export class Traversal {
return this;
}
- /** @returns {Bytecode} */
- getBytecode() {
- return this.bytecode;
+ /** @returns {GremlinLang} */
+ getGremlinLang(): GremlinLang {
+ return this.gremlinLang;
}
/**
@@ -86,7 +86,7 @@ export class Traversal {
* @returns {Promise}
*/
iterate() {
- this.bytecode.addStep('discard');
+ this.gremlinLang.addStep('discard');
return this._applyStrategies().then(() => {
let it;
while ((it = this._getNext()) && !it.done) {
@@ -133,15 +133,15 @@ export class Traversal {
* @returns {Array}
*/
toJSON() {
- return this.bytecode.stepInstructions;
+ return this.gremlinLang.getGremlin();
}
/**
- * Returns the Bytecode JSON representation of the traversal
+ * Returns the GremlinLang representation of the traversal
* @returns {String}
*/
toString() {
- return this.bytecode.toString();
+ return this.gremlinLang.getGremlin();
}
}
@@ -255,18 +255,18 @@ export class P<T1 = any, T2 = any> {
* @returns {string}
*/
toString() {
- function formatValue(value: T1 | T2): any {
+ function formatValue(value: T1 | T2): string {
if (Array.isArray(value)) {
const acc = [];
for (const item of value) {
acc.push(formatValue(item));
}
- return acc;
+ return '[' + acc.join(', ') + ']';
}
if (value && typeof value === 'string') {
return `'${value}'`;
}
- return value;
+ return String(value);
}
if (this.other === undefined || this.other === null) {
@@ -511,7 +511,7 @@ export class EnumValue {
) {}
toString() {
- return this.elementName;
+ return this.typeName + '.' + this.elementName;
}
}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/GraphBinary.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/GraphBinary.js
index 4e78e90bbc..ddd7c07045 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/GraphBinary.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/GraphBinary.js
@@ -78,7 +78,6 @@ import PathSerializer from './internals/PathSerializer.js';
import PropertySerializer from './internals/PropertySerializer.js';
import VertexSerializer from './internals/VertexSerializer.js';
import VertexPropertySerializer from './internals/VertexPropertySerializer.js';
-import BytecodeSerializer from './internals/BytecodeSerializer.js';
import PSerializer from './internals/PSerializer.js';
import TraverserSerializer from './internals/TraverserSerializer.js';
import EnumSerializer from './internals/EnumSerializer.js';
@@ -123,7 +122,6 @@ ioc.pathSerializer = new PathSerializer(ioc);
ioc.propertySerializer = new PropertySerializer(ioc);
ioc.vertexSerializer = new VertexSerializer(ioc);
ioc.vertexPropertySerializer = new VertexPropertySerializer(ioc);
-ioc.bytecodeSerializer = new BytecodeSerializer(ioc);
ioc.pSerializer = new PSerializer(ioc);
ioc.traverserSerializer = new TraverserSerializer(ioc);
ioc.enumSerializer = new EnumSerializer(ioc);
@@ -167,7 +165,6 @@ export const {
propertySerializer,
vertexSerializer,
vertexPropertySerializer,
- bytecodeSerializer,
pSerializer,
traverserSerializer,
enumSerializer,
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/AnySerializer.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/AnySerializer.js
index a378b3d5fe..c550dc2a9d 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/AnySerializer.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/AnySerializer.js
@@ -36,7 +36,6 @@ export default class AnySerializer {
ioc.booleanSerializer,
ioc.offsetDateTimeSerializer,
ioc.dateSerializer,
- ioc.bytecodeSerializer,
ioc.pSerializer,
ioc.traverserSerializer,
ioc.enumSerializer,
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/BytecodeSerializer.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/BytecodeSerializer.js
deleted file mode 100644
index a2c0d74b21..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/BytecodeSerializer.js
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * @author Igor Ostapenko
- */
-
-import { Buffer } from 'buffer';
-import Bytecode from '../../../../process/bytecode.js';
-import { Traversal } from '../../../../process/traversal.js';
-
-export default class BytecodeSerializer {
- constructor(ioc) {
- this.ioc = ioc;
- this.ioc.serializers[ioc.DataType.BYTECODE] = this;
- }
-
- canBeUsedFor(value) {
- return value instanceof Bytecode || value instanceof Traversal;
- }
-
- serialize(item, fullyQualifiedFormat = true) {
- if (item === undefined || item === null) {
- if (fullyQualifiedFormat) {
- return Buffer.from([this.ioc.DataType.BYTECODE, 0x01]);
- }
- const steps_length = [0x00, 0x00, 0x00, 0x00]; // 0
- const sources_length = [0x00, 0x00, 0x00, 0x00]; // 0
- return Buffer.from([...steps_length, ...sources_length]);
- }
-
- if (item instanceof Traversal) {
- item = item.getBytecode();
- }
-
- const bufs = [];
- if (fullyQualifiedFormat) {
- bufs.push(Buffer.from([this.ioc.DataType.BYTECODE, 0x00]));
- }
-
- // {steps_length}{step_0}...{step_n}
- bufs.push(this.ioc.intSerializer.serialize(item.stepInstructions.length, false)); // TODO: what if steps_length > INT32_MAX
- for (let i = 0; i < item.stepInstructions.length; i++) {
- // {step_i} is composed of {name}{values_length}{value_0}...{value_n}
- const step = item.stepInstructions[i];
- const name = step[0];
- const values_length = step.length - 1;
- bufs.push(this.ioc.stringSerializer.serialize(name, false));
- bufs.push(this.ioc.intSerializer.serialize(values_length, false));
- for (let j = 0; j < values_length; j++) {
- bufs.push(this.ioc.anySerializer.serialize(step[1 + j], true));
- }
- }
-
- // {sources_length}{source_0}...{source_n}
- bufs.push(this.ioc.intSerializer.serialize(item.sourceInstructions.length, false)); // TODO: what if sources_length > INT32_MAX
- for (let i = 0; i < item.sourceInstructions.length; i++) {
- // {source_i} is composed of {name}{values_length}{value_0}...{value_n}
- const source = item.sourceInstructions[i];
- const name = source[0];
- const values_length = source.length - 1;
- bufs.push(this.ioc.stringSerializer.serialize(name, false));
- bufs.push(this.ioc.intSerializer.serialize(values_length, false));
- for (let j = 0; j < values_length; j++) {
- bufs.push(this.ioc.anySerializer.serialize(source[1 + j], true));
- }
- }
-
- return Buffer.concat(bufs);
- }
-
- deserialize(buffer, fullyQualifiedFormat = true) {
- let len = 0;
- let cursor = buffer;
-
- try {
- if (buffer === undefined || buffer === null || !(buffer instanceof Buffer)) {
- throw new Error('buffer is missing');
- }
- if (buffer.length < 1) {
- throw new Error('buffer is empty');
- }
-
- if (fullyQualifiedFormat) {
- const type_code = cursor.readUInt8();
- len++;
- if (type_code !== this.ioc.DataType.BYTECODE) {
- throw new Error('unexpected {type_code}');
- }
- cursor = cursor.slice(1);
-
- if (cursor.length < 1) {
- throw new Error('{value_flag} is missing');
- }
- const value_flag = cursor.readUInt8();
- len++;
- if (value_flag === 1) {
- return { v: null, len };
- }
- if (value_flag !== 0) {
- throw new Error('unexpected {value_flag}');
- }
- cursor = cursor.slice(1);
- }
-
- const v = new Bytecode();
-
- // steps
-
- let steps_length, steps_length_len;
- try {
- ({ v: steps_length, len: steps_length_len } = this.ioc.intSerializer.deserialize(cursor, false));
- len += steps_length_len;
- } catch (err) {
- err.message = '{steps_length}: ' + err.message;
- throw err;
- }
- if (steps_length < 0) {
- throw new Error('{steps_length} is less than zero');
- }
- cursor = cursor.slice(steps_length_len);
-
- // {step_i} is composed of {name}{values_length}{value_0}...{value_n}
- for (let i = 0; i < steps_length; i++) {
- // {name} is a String
- let name, name_len;
- try {
- ({ v: name, len: name_len } = this.ioc.stringSerializer.deserialize(cursor, false));
- len += name_len;
- } catch (err) {
- err.message = `{step_${i}} {name}: ` + err.message;
- throw err;
- }
- cursor = cursor.slice(name_len);
-
- // {values_length} is an Int describing the amount values
- let values_length, values_length_len;
- try {
- ({ v: values_length, len: values_length_len } = this.ioc.intSerializer.deserialize(cursor, false));
- len += values_length_len;
- } catch (err) {
- err.message = `{step_${i}} {values_length}: ` + err.message;
- throw err;
- }
- if (values_length < 0) {
- throw new Error(`{step_${i}} {values_length} is less than zero`);
- }
- cursor = cursor.slice(values_length_len);
-
- // {value_i} is a fully qualified typed value composed of {type_code}{type_info}{value_flag}{value} describing the step argument
- const values = [];
- let value, value_len;
- for (let j = 0; j < values_length; j++) {
- try {
- ({ v: value, len: value_len } = this.ioc.anySerializer.deserialize(cursor));
- len += value_len;
- values.push(value);
- } catch (err) {
- err.message = `{step_${i}} {value_${j}}: ` + err.message;
- throw err;
- }
- cursor = cursor.slice(value_len);
- }
-
- v.addStep(name, values);
- }
-
- // sources
-
- let sources_length, sources_length_len;
- try {
- ({ v: sources_length, len: sources_length_len } = this.ioc.intSerializer.deserialize(cursor, false));
- len += sources_length_len;
- } catch (err) {
- err.message = '{sources_length}: ' + err.message;
- throw err;
- }
- if (sources_length < 0) {
- throw new Error('{sources_length} is less than zero');
- }
- cursor = cursor.slice(sources_length_len);
-
- // {source_i} is composed of {name}{values_length}{value_0}...{value_n}
- for (let i = 0; i < sources_length; i++) {
- // {name} is a String
- let name, name_len;
- try {
- ({ v: name, len: name_len } = this.ioc.stringSerializer.deserialize(cursor, false));
- len += name_len;
- } catch (err) {
- err.message = `{source_${i}} {name}: ` + err.message;
- throw err;
- }
- cursor = cursor.slice(name_len);
-
- // {values_length} is an Int describing the amount values
- let values_length, values_length_len;
- try {
- ({ v: values_length, len: values_length_len } = this.ioc.intSerializer.deserialize(cursor, false));
- len += values_length_len;
- } catch (err) {
- err.message = `{source_${i}} {values_length}: ` + err.message;
- throw err;
- }
- if (values_length < 0) {
- throw new Error(`{source_${i}} {values_length} is less than zero`);
- }
- cursor = cursor.slice(values_length_len);
-
- // {value_i} is a fully qualified typed value composed of {type_code}{type_info}{value_flag}{value}
- const values = [];
- let value, value_len;
- for (let j = 0; j < values_length; j++) {
- try {
- ({ v: value, len: value_len } = this.ioc.anySerializer.deserialize(cursor));
- len += value_len;
- values.push(value);
- } catch (err) {
- err.message = `{source_${i}} {value_${j}}: ` + err.message;
- throw err;
- }
- cursor = cursor.slice(value_len);
- }
-
- v.addSource(name, values);
- }
-
- return { v, len };
- } catch (err) {
- throw this.ioc.utils.des_error({ serializer: this, args: arguments, cursor, err });
- }
- }
-}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/GraphBinaryWriter.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/GraphBinaryWriter.js
index d69640b3f3..e5b62115f3 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/GraphBinaryWriter.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/binary/internals/GraphBinaryWriter.js
@@ -46,39 +46,6 @@ export default class GraphBinaryWriter {
];
return Buffer.concat(bufs);
- /*// Detailed example for a quick reference:
- // {version}
- 0x81,
- // {request_id} UUID
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
- // {op} String
- 0x00,0x00,0x00,0x08, ...Buffer.from('bytecode'),
- // {processor} String
- 0x00,0x00,0x00,0x09, ...Buffer.from('traversal'),
- // {args} Map
- 0x00,0x00,0x00,0x02,
- // 1.
- // args.aliases key String
- 0x03,0x00, 0x00,0x00,0x00,0x07, ...Buffer.from('aliases'),
- // args.aliases value Map
- 0x0A,0x00, 0x00,0x00,0x00,0x01,
- // aliases.g key String
- 0x03,0x00, 0x00,0x00,0x00,0x01, ...Buffer.from('g'),
- // aliases.g value String
- 0x03,0x00, 0x00,0x00,0x00,0x01, ...Buffer.from('g'),
- // 2.
- // args.gremlin key String
- 0x03,0x00, 0x00,0x00,0x00,0x07, ...Buffer.from('gremlin'),
- // args.gremlin value Bytecode
- 0x15,0x00,
- // {steps_length}
- 0x00,0x00,0x00,0x01,
- // step 1 - {name} String
- 0x00,0x00,0x00,0x01, ...Buffer.from('V'),
- // step 1 - {values_length} Int
- 0x00,0x00,0x00,0x00,
- // {sources_length}
- 0x00,0x00,0x00,0x00,
- */
+
}
}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/graph-serializer.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/graph-serializer.ts
index c41a602774..2d7bf12a51 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/graph-serializer.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/graph-serializer.ts
@@ -22,10 +22,8 @@
*/
import { Buffer } from 'buffer';
-import Bytecode from '../../process/bytecode.js';
import {
BulkSetSerializer,
- BytecodeSerializer,
DateSerializer,
OffsetDateTimeSerializer,
DirectionSerializer,
@@ -148,10 +146,6 @@ export class GraphSON2Writer {
args: this._adaptArgs(args, true),
};
- if (req.args['gremlin'] instanceof Bytecode) {
- req.args['gremlin'] = this.adaptObject(req.args['gremlin']);
- }
-
return Buffer.from(JSON.stringify(req));
}
@@ -319,7 +313,6 @@ const graphSON3Deserializers = Object.assign({}, graphSON2Deserializers, {
const graphSON2Serializers = [
NumberSerializer,
OffsetDateTimeSerializer,
- BytecodeSerializer,
TraverserSerializer,
TraversalStrategySerializer,
PSerializer,
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/type-serializers.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/type-serializers.ts
index da2143421d..352c13582b 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/type-serializers.ts
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/type-serializers.ts
@@ -23,7 +23,6 @@
import * as t from '../../process/traversal.js';
import * as ts from '../../process/traversal-strategy.js';
-import Bytecode from '../../process/bytecode.js';
import * as g from '../graph.js';
import * as utils from '../../utils.js';
@@ -131,43 +130,6 @@ export class LongSerializer extends TypeSerializer<utils.Long> {
}
}
-export class BytecodeSerializer extends TypeSerializer<Bytecode> {
- serialize(item: Bytecode) {
- let bytecode = item;
- if (item instanceof t.Traversal) {
- bytecode = item.getBytecode();
- }
- const result: Partial<SerializedValue> = {};
- result[typeKey] = 'g:Bytecode';
- const resultValue: any = (result[valueKey] = {});
- const sources = this._serializeInstructions(bytecode.sourceInstructions);
- if (sources) {
- resultValue['source'] = sources;
- }
- const steps = this._serializeInstructions(bytecode.stepInstructions);
- if (steps) {
- resultValue['step'] = steps;
- }
- return result as SerializedValue;
- }
-
- _serializeInstructions(instructions: any[]) {
- if (instructions.length === 0) {
- return null;
- }
- const result = new Array(instructions.length);
- result[0] = instructions[0];
- for (let i = 0; i < instructions.length; i++) {
- result[i] = instructions[i].map((item: unknown) => this.writer.adaptObject(item));
- }
- return result;
- }
-
- canBeUsedFor(value: unknown) {
- return value instanceof Bytecode || value instanceof t.Traversal;
- }
-}
-
export class PSerializer extends TypeSerializer<t.P> {
/** @param {P} item */
serialize(item: t.P) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/bytecode-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/bytecode-test.js
deleted file mode 100644
index 3e7eaae5e4..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/bytecode-test.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * @author Serhiy Salo
- */
-
-import assert from 'assert';
-import { Graph } from '../../lib/structure/graph.js';
-import { statics } from '../../lib/process/graph-traversal.js';
-const __ = statics;
-import { ReadOnlyStrategy } from '../../lib/process/traversal-strategy.js';
-
-describe('Bytecode', () => {
-
- describe('#toString()', () => {
- it('should produce valid string representation of bytecode', () => {
- const g = new Graph().traversal();
- const bytecode = g.V().hasLabel("person").has("name", "peter");
- assert.ok(bytecode);
- assert.strictEqual(bytecode.toString(), '[[],[["V"],["hasLabel","person"],["has","name","peter"]]]');
- });
- it('should produce valid string representation of bytecode with reference to inner steps', () => {
- const g = new Graph().traversal();
- const bytecode = g.V().hasLabel("airport").where(__.outE("route").hasId(7753));
- assert.ok(bytecode);
- assert.strictEqual(bytecode.toString(), '[[],[["V"],["hasLabel","airport"],["where",[["outE","route"],["hasId",7753]]]]]');
- });
- it('should produce valid string representation of bytecode with multiple parameters', () => {
- const g = new Graph().traversal();
- const bytecode = g.V().has('person', 'name', 'marko');
- assert.ok(bytecode);
- assert.strictEqual(bytecode.toString(), '[[],[["V"],["has","person","name","marko"]]]');
- });
- it('should produce valid string representation of bytecode with strategies', () => {
- const g = new Graph().traversal();
- const bytecode = g.with_('enabled').withStrategies(new ReadOnlyStrategy()).V();
- assert.ok(bytecode);
- assert.strictEqual(bytecode.toString(), '[[["withStrategies",{"fqcn":"org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.OptionsStrategy","configuration":{"enabled":true}}],["withStrategies",{"fqcn":"org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy","configuration":{}}]],[["V"]]]');
- });
- });
-});
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/exports-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/exports-test.js
index 65ab268b46..6335c348d3 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/exports-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/exports-test.js
@@ -28,7 +28,7 @@ describe('API', function () {
it('should export fields under process', function () {
assert.ok(glvModule);
assert.ok(glvModule.process);
- assert.strictEqual(typeof glvModule.process.Bytecode, 'function');
+ assert.strictEqual(typeof glvModule.process.GremlinLang, 'function');
assert.strictEqual(typeof glvModule.process.EnumValue, 'function');
assert.strictEqual(typeof glvModule.process.P, 'function');
assert.strictEqual(typeof glvModule.process.Traversal, 'function');
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/AnySerializer-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/AnySerializer-test.js
index 575c10e03a..9e42fb70cf 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/AnySerializer-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/AnySerializer-test.js
@@ -28,9 +28,9 @@ import { DataType, anySerializer } from '../../../lib/structure/io/binary/GraphB
import { Vertex, VertexProperty, Edge, Path, Property } from '../../../lib/structure/graph.js';
import { Traverser, P, TextP, EnumValue } from '../../../lib/process/traversal.js';
import { OptionsStrategy } from '../../../lib/process/traversal-strategy.js';
-import Bytecode from '../../../lib/process/bytecode.js';
+
import { GraphTraversal } from '../../../lib/process/graph-traversal.js';
-const g = () => new GraphTraversal(undefined, undefined, new Bytecode());
+const g = () => new GraphTraversal(undefined, undefined);
const { from, concat } = Buffer;
@@ -80,27 +80,7 @@ describe('GraphBinary.AnySerializer', () => {
{ v:new Date('2023-08-02T01:23:45-07:30'),
b:[DataType.OFFSETDATETIME,0x00, 0x00,0x00,0x07,0xe7,0x08,0x02,0x00,0x00,0x1d,0x20,0x66,0xbf,0xba,0x00,0x00,0x00,0x00,0x00] },
- // BytecodeSerializer
- // Traversal type
- { v: g().V(),
- b: [
- DataType.BYTECODE,0x00,
- 0x00,0x00,0x00,0x01, // {steps_length}
- 0x00,0x00,0x00,0x01, 0x56, // V
- 0x00,0x00,0x00,0x00, // (void)
- 0x00,0x00,0x00,0x00, // {sources_length}
- ]
- },
- // Bytecode type
- { v: g().V().getBytecode(),
- b: [
- DataType.BYTECODE,0x00,
- 0x00,0x00,0x00,0x01, // {steps_length}
- 0x00,0x00,0x00,0x01, 0x56, // V
- 0x00,0x00,0x00,0x00, // (void)
- 0x00,0x00,0x00,0x00, // {sources_length}
- ]
- },
+
// TraverserSerializer
{ v: new Traverser("A1", 16),
@@ -495,9 +475,7 @@ describe('GraphBinary.AnySerializer', () => {
// BINDING
// TODO: it's ignored for now
- // BYTECODE
- { v:null, b:[0x15,0x01] },
- { v:new Bytecode(), b:[0x15,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00] },
+
// CARDINALITY
{ v:null, b:[0x16,0x01] },
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/BytecodeSerializer-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/BytecodeSerializer-test.js
deleted file mode 100644
index 9ed97b5580..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/BytecodeSerializer-test.js
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * @author Igor Ostapenko
- */
-
-import { ser_title, des_title, cbuf_title } from './utils.js';
-import assert from 'assert';
-import { bytecodeSerializer } from '../../../lib/structure/io/binary/GraphBinary.js';
-
-import { Traverser, Traversal } from '../../../lib/process/traversal.js';
-import Bytecode from '../../../lib/process/bytecode.js';
-import { GraphTraversal } from '../../../lib/process/graph-traversal.js';
-import { ReservedKeysVerificationStrategy } from '../../../lib/process/traversal-strategy.js';
-
-const g = (strategy) => {
- const bc = new Bytecode();
- if (strategy)
- bc.addSource('withStrategies', [ strategy ]);
- return new GraphTraversal(undefined, undefined, bc);
-}
-
-const { from, concat } = Buffer;
-
-describe('GraphBinary.BytecodeSerializer', () => {
-
- const type_code = from([0x15]);
- const value_flag = from([0x00]);
-
- const cases = [
- { v:undefined, fq:1, b:[0x15,0x01], av:null },
- { v:undefined, fq:0, b:[0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00], av:g() },
- { v:null, fq:1, b:[0x15,0x01] },
- { v:null, fq:0, b:[0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00], av:g() },
-
- { v: g(),
- b: [
- 0x00,0x00,0x00,0x00, // {steps_length}
- 0x00,0x00,0x00,0x00, // {sources_length}
- ]},
-
- { v: g().V(),
- b: [
- 0x00,0x00,0x00,0x01, // {steps_length}
- 0x00,0x00,0x00,0x01, 0x56, // V
- 0x00,0x00,0x00,0x00, // (void)
- 0x00,0x00,0x00,0x00, // {sources_length}
- ]},
-
- { v: g().V().hasLabel('Person').has('age', 42),
- b: [
- 0x00,0x00,0x00,0x03, // {steps_length}
- 0x00,0x00,0x00,0x01, 0x56, // V
- 0x00,0x00,0x00,0x00, // ([0])
- 0x00,0x00,0x00,0x08, 0x68,0x61,0x73,0x4C,0x61,0x62,0x65,0x6C, // hasLabel
- 0x00,0x00,0x00,0x01, // ([1])
- 0x03,0x00, 0x00,0x00,0x00,0x06, 0x50,0x65,0x72,0x73,0x6F,0x6E, // 'Person'
- 0x00,0x00,0x00,0x03, 0x68,0x61,0x73, // has
- 0x00,0x00,0x00,0x02, // ([2])
- 0x03,0x00, 0x00,0x00,0x00,0x03, 0x61,0x67,0x65, // 'age'
- 0x01,0x00, 0x00,0x00,0x00,0x2A, // 42
- 0x00,0x00,0x00,0x00, // {sources_length}
- ]},
-
- { ser:1, v: g(new ReservedKeysVerificationStrategy({logWarnings: false, throwException: true})).V().hasLabel('Person').has('age', 42),
- b: [
- 0x00,0x00,0x00,0x03, // {steps_length}
- 0x00,0x00,0x00,0x01, 0x56, // V
- 0x00,0x00,0x00,0x00, // ([0])
- 0x00,0x00,0x00,0x08, 0x68,0x61,0x73,0x4C,0x61,0x62,0x65,0x6C, // hasLabel
- 0x00,0x00,0x00,0x01, // ([1])
- 0x03,0x00, 0x00,0x00,0x00,0x06, 0x50,0x65,0x72,0x73,0x6F,0x6E, // 'Person'
- 0x00,0x00,0x00,0x03, 0x68,0x61,0x73, // has
- 0x00,0x00,0x00,0x02, // ([2])
- 0x03,0x00, 0x00,0x00,0x00,0x03, 0x61,0x67,0x65, // 'age'
- 0x01,0x00, 0x00,0x00,0x00,0x2A, // 42
- 0x00,0x00,0x00,0x01, // {sources_length}
- 0x00,0x00,0x00,0x0E, ...from('withStrategies'),
- 0x00,0x00,0x00,0x01,
- 0x29,0x00, 0x00,0x00,0x00,0x65, ...from('org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReservedKeysVerificationStrategy'),
- 0x00,0x00,0x00,0x03, // configuration map size
- 0x03,0x00, 0x00,0x00,0x00,0x0B, ...from('logWarnings'),
- 0x27,0x00, 0x00, // false
- 0x03,0x00, 0x00,0x00,0x00,0x0E, ...from('throwException'),
- 0x27,0x00, 0x01, // true
- 0x03,0x00, 0x00,0x00,0x00,0x04, ...from('keys'),
- 0x09,0x00, 0x00,0x00,0x00,0x02,
- 0x03,0x00, 0x00,0x00,0x00,0x02, ...from('id'),
- 0x03,0x00, 0x00,0x00,0x00,0x05, ...from('label'),
- ]},
-
- { des:1, err:/buffer is missing/, fq:1, b:undefined },
- { des:1, err:/buffer is missing/, fq:0, b:undefined },
- { des:1, err:/buffer is missing/, fq:1, b:null },
- { des:1, err:/buffer is missing/, fq:0, b:null },
- { des:1, err:/buffer is empty/, fq:1, b:[] },
- { des:1, err:/buffer is empty/, fq:0, b:[] },
-
- { des:1, err:/unexpected {type_code}/, fq:1, b:[0x00] },
- { des:1, err:/unexpected {type_code}/, fq:1, b:[0x14] },
- { des:1, err:/unexpected {type_code}/, fq:1, b:[0x16] },
- { des:1, err:/unexpected {type_code}/, fq:1, b:[0x51] },
- { des:1, err:/unexpected {type_code}/, fq:1, b:[0x85] },
- { des:1, err:/unexpected {type_code}/, fq:1, b:[0x5F] },
- { des:1, err:/unexpected {type_code}/, fq:1, b:[0xFF] },
-
- { des:1, err:/{value_flag} is missing/, fq:1, b:[0x15] },
- { des:1, err:/unexpected {value_flag}/, fq:1, b:[0x15,0x10] },
- { des:1, err:/unexpected {value_flag}/, fq:1, b:[0x15,0x02] },
- { des:1, err:/unexpected {value_flag}/, fq:1, b:[0x15,0x0F] },
- { des:1, err:/unexpected {value_flag}/, fq:1, b:[0x15,0xFF] },
-
- { des:1, err:/{steps_length} is less than zero/, b:[0xFF,0xFF,0xFF,0xFF] },
- { des:1, err:/{steps_length} is less than zero/, b:[0x80,0x00,0x00,0x00] },
-
- { des:1, err:/{sources_length} is less than zero/, b:[0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF] },
- { des:1, err:/{sources_length} is less than zero/, b:[0x00,0x00,0x00,0x00, 0x80,0x00,0x00,0x00] },
- ];
-
- describe('#serialize', () =>
- cases
- .filter(({des}) => !des)
- .forEach(({ v, fq, b }, i) => it(ser_title({i,v}), () => {
- b = from(b);
-
- // when fq is under control
- if (fq !== undefined) {
- assert.deepEqual( bytecodeSerializer.serialize(v, fq), b );
- return;
- }
-
- // generic case
- v = v.getBytecode();
- assert.deepEqual( bytecodeSerializer.serialize(v, true), concat([type_code, value_flag, b]) );
- assert.deepEqual( bytecodeSerializer.serialize(v, false), concat([ b]) );
- }))
- );
-
- describe('#deserialize', () =>
- cases
- .filter(({ser}) => !ser)
- .forEach(({ v, fq, b, av, err }, i) => it(des_title({i,b}), () => {
- if (Array.isArray(b))
- b = from(b);
-
- // wrong binary
- if (err !== undefined) {
- if (fq !== undefined)
- assert.throws(() => bytecodeSerializer.deserialize(b, fq), { message: err });
- else {
- assert.throws(() => bytecodeSerializer.deserialize(concat([type_code, value_flag, b]), true), { message: err });
- assert.throws(() => bytecodeSerializer.deserialize(concat([ b]), false), { message: err });
- }
- return;
- }
-
- if (av !== undefined)
- v = av;
- if (v)
- v = v.getBytecode();
- const len = b.length;
-
- // when fq is under control
- if (fq !== undefined) {
- assert.deepStrictEqual( bytecodeSerializer.deserialize(b, fq), {v,len} );
- return;
- }
-
- // generic case
- assert.deepStrictEqual( bytecodeSerializer.deserialize(concat([type_code, value_flag, b]), true), {v,len:len+2} );
- assert.deepStrictEqual( bytecodeSerializer.deserialize(concat([ b]), false), {v,len:len+0} );
- }))
- );
-
- describe('#canBeUsedFor', () =>
- // most of the cases are implicitly tested via AnySerializer.serialize() tests
- [
- { v: null, e: false },
- { v: undefined, e: false },
- { v: {}, e: false },
- { v: new Traverser(), e: false },
- { v: [], e: false },
- { v: [0], e: false },
- { v: [undefined], e: false },
- { v: [new Bytecode()], e: false },
- { v: new Bytecode(), e: true },
- { v: [new Traversal], e: false },
- { v: new Traversal, e: true },
- ].forEach(({ v, e }, i) => it(cbuf_title({i,v}), () =>
- assert.strictEqual( bytecodeSerializer.canBeUsedFor(v), e )
- ))
- );
-
-});
-
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryReader-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryReader-test.js
index 1f49b0bb4e..907c271deb 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryReader-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryReader-test.js
@@ -25,9 +25,9 @@ import assert from 'assert';
import { graphBinaryReader } from '../../../lib/structure/io/binary/GraphBinary.js';
import { Traverser } from '../../../lib/process/traversal.js';
-import Bytecode from '../../../lib/process/bytecode.js';
+
import { GraphTraversal } from '../../../lib/process/graph-traversal.js';
-const g = () => new GraphTraversal(undefined, undefined, new Bytecode());
+const g = () => new GraphTraversal(undefined, undefined);
const { from } = Buffer;
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js
index 277f83c283..6dacf65bf4 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js
@@ -24,9 +24,8 @@
import assert from 'assert';
import { graphBinaryWriter } from '../../../lib/structure/io/binary/GraphBinary.js';
-import Bytecode from '../../../lib/process/bytecode.js';
-import { GraphTraversal } from '../../../lib/process/graph-traversal.js';
-const g = () => new GraphTraversal(undefined, undefined, new Bytecode());
+
+
const { from, concat } = Buffer;
@@ -34,48 +33,6 @@ describe('GraphBinary.Writer', () => {
describe('#writeRequest', () =>
[
- {
- r: {
- requestId: '00010203-0405-0607-0809-0A0b0c0D0e0F',
- op: 'bytecode',
- processor: 'traversal',
- args: { aliases: {g:'g'}, gremlin: g().V().getBytecode() },
- },
- e: [
- // {version}
- 0x81,
- // {request_id} UUID
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
- // {op} String
- 0x00,0x00,0x00,0x08, ...from('bytecode'),
- // {processor} String
- 0x00,0x00,0x00,0x09, ...from('traversal'),
- // {args} Map
- 0x00,0x00,0x00,0x02,
- // 1.
- // args.aliases key String
- 0x03,0x00, 0x00,0x00,0x00,0x07, ...from('aliases'),
- // args.aliases value Map
- 0x0A,0x00, 0x00,0x00,0x00,0x01,
- // aliases.g key String
- 0x03,0x00, 0x00,0x00,0x00,0x01, ...from('g'),
- // aliases.g value String
- 0x03,0x00, 0x00,0x00,0x00,0x01, ...from('g'),
- // 2.
- // args.gremlin key String
- 0x03,0x00, 0x00,0x00,0x00,0x07, ...from('gremlin'),
- // args.gremlin value Bytecode
- 0x15,0x00,
- // {steps_length}
- 0x00,0x00,0x00,0x01,
- // step 1 - {name} String
- 0x00,0x00,0x00,0x01, ...from('V'),
- // step 1 - {values_length} Int
- 0x00,0x00,0x00,0x00,
- // {sources_length}
- 0x00,0x00,0x00,0x00,
- ],
- },
].forEach(({ r, e }, i) => it(`should be able to handle request of case #${i}`, () => assert.deepEqual(
graphBinaryWriter.writeRequest(r),
from(e),
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/MapSerializer-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/MapSerializer-test.js
index 0043b058fb..d123f42d66 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/MapSerializer-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/graphbinary/MapSerializer-test.js
@@ -26,9 +26,8 @@ import assert from 'assert';
import { mapSerializer } from '../../../lib/structure/io/binary/GraphBinary.js';
import { Traverser } from '../../../lib/process/traversal.js';
-import Bytecode from '../../../lib/process/bytecode.js';
-import { GraphTraversal } from '../../../lib/process/graph-traversal.js';
-const g = () => new GraphTraversal(undefined, undefined, new Bytecode());
+
+
const { from, concat } = Buffer;
@@ -77,28 +76,7 @@ describe('GraphBinary.MapSerializer', () => {
]
},
- { v:{ aliases: new Map([ ['g','g'] ]), gremlin: g().V().getBytecode() },
- b:[0x00,0x00,0x00,0x02,
- /*'aliases'*/
- 0x03,0x00, 0x00,0x00,0x00,0x07, ...from('aliases'),
- /*aliases map*/
- 0x0A,0x00, 0x00,0x00,0x00,0x01,
- /*'g'*/0x03,0x00,0x00,0x00,0x00,0x01,0x67, /*'g'*/0x03,0x00,0x00,0x00,0x00,0x01,0x67,
-
- /*'gremlin'*/
- 0x03,0x00, 0x00,0x00,0x00,0x07, ...from('gremlin'),
- /*gremlin bytecode*/
- 0x15,0x00,
- // {steps_length}
- 0x00,0x00,0x00,0x01,
- // step 1 - {name} String
- 0x00,0x00,0x00,0x01, ...from('V'),
- // step 1 - {values_length} Int
- 0x00,0x00,0x00,0x00,
- // {sources_length}
- 0x00,0x00,0x00,0x00,
- ]
- },
+
{ des:1, err:/buffer is missing/, fq:1, b:undefined },
{ des:1, err:/buffer is missing/, fq:0, b:undefined },
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/gremlin-lang-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/gremlin-lang-test.js
new file mode 100644
index 0000000000..1168a7c0d5
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/gremlin-lang-test.js
@@ -0,0 +1,387 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import assert from 'assert';
+import { GraphTraversalSource, statics as __, CardinalityValue } from '../../lib/process/graph-traversal.js';
+import { P, TextP, t as T, order as Order, scope as Scope, column as Column,
+ operator as Operator, pop as Pop, cardinality as Cardinality,
+ withOptions as WithOptions, direction } from '../../lib/process/traversal.js';
+import { ReadOnlyStrategy, SubgraphStrategy, OptionsStrategy,
+ PartitionStrategy, SeedStrategy } from '../../lib/process/traversal-strategy.js';
+import { Graph, Vertex } from '../../lib/structure/graph.js';
+import { TraversalStrategies } from '../../lib/process/traversal-strategy.js';
+import { Long } from '../../lib/utils.js';
+import GremlinLang from '../../lib/process/gremlin-lang.js';
+
+const g = new GraphTraversalSource(new Graph(), new TraversalStrategies());
+
+describe('GremlinLang', function () {
+ describe('End-to-end tests', function () {
+ const tests = [
+ // #0
+ [g.V(), 'g.V()'],
+ // #1
+ [g.V('1','2','3','4'), "g.V('1','2','3','4')"],
+ // #2
+ [g.V('3').valueMap(true), "g.V('3').valueMap(true)"],
+ // #3
+ [g.V().constant(5), 'g.V().constant(5)'],
+ // #4
+ [g.V().constant(1.5), 'g.V().constant(1.5)'],
+ // #5
+ [g.V().constant('Hello'), "g.V().constant('Hello')"],
+ // #6
+ [g.V().hasLabel('airport').limit(5), "g.V().hasLabel('airport').limit(5)"],
+ // #7
+ [g.V().hasLabel(P.within(['a','b','c'])), "g.V().hasLabel(within(['a','b','c']))"],
+ // #8
+ [g.V().hasLabel('airport','continent').out().limit(5), "g.V().hasLabel('airport','continent').out().limit(5)"],
+ // #9
+ [g.V().hasLabel('airport').out().values('code').limit(5), "g.V().hasLabel('airport').out().values('code').limit(5)"],
+ // #10
+ [g.V('3').as('a').out('route').limit(10).where(P.eq('a')).by('region'), "g.V('3').as('a').out('route').limit(10).where(eq('a')).by('region')"],
+ // #11
+ [g.V('3').repeat(__.out('route').simplePath()).times(2).path().by('code'), "g.V('3').repeat(__.out('route').simplePath()).times(2).path().by('code')"],
+ // #12
+ [g.V().has('airport','region','US-TX').order().by('code'), "g.V().has('airport','region','US-TX').order().by('code')"],
+ // #13
+ [g.V('3').union(__.values('code'),__.values('city')), "g.V('3').union(__.values('code'),__.values('city'))"],
+ // #14
+ [g.V('3').as('a').out('route','routes').path().by('code'), "g.V('3').as('a').out('route','routes').path().by('code')"],
+ // #15
+ [g.V().where(__.values('runways').is(5)), "g.V().where(__.values('runways').is(5))"],
+ // #16
+ [g.V('3').repeat(__.out()).until(__.has('code','AGR')).path().by('code').limit(5), "g.V('3').repeat(__.out()).until(__.has('code','AGR')).path().by('code').limit(5)"],
+ // #17
+ [g.V().order().by(__.id()), 'g.V().order().by(__.id())'],
+ // #18
+ [g.V().order().by(T.id), 'g.V().order().by(T.id)'],
+ // #19
+ [g.V().order().by(__.id(),Order.desc), 'g.V().order().by(__.id(),Order.desc)'],
+ // #20
+ [g.V().order().by('code',Order.desc), "g.V().order().by('code',Order.desc)"],
+ // #21
+ [g.V().hasLabel('airport').dedup().local(__.values('code','city').fold()), "g.V().hasLabel('airport').dedup().local(__.values('code','city').fold())"],
+ // #22
+ [g.V().count(Scope.local), 'g.V().count(Scope.local)'],
+ // #23
+ [g.E().count(), 'g.E().count()'],
+ // #24
+ [g.V('3').outE('route').inV().path().by('code').by('dist'), "g.V('3').outE('route').inV().path().by('code').by('dist')"],
+ // #25
+ [g.V('3').propertyMap().select(Column.keys), "g.V('3').propertyMap().select(Column.keys)"],
+ // #26
+ [g.V('3').propertyMap().select(Column.values), "g.V('3').propertyMap().select(Column.values)"],
+ // #27
+ [g.V().has('airport','code','AUS').values('runways').math('_ + 1'), "g.V().has('airport','code','AUS').values('runways').math('_ + 1')"],
+ // #28
+ [g.V('3').emit().repeat(__.out()).times(3).limit(5).path().by('code'), "g.V('3').emit().repeat(__.out()).times(3).limit(5).path().by('code')"],
+ // #29
+ [g.V().match(__.as('a').has('code','AUS'),__.as('a').out('route').as('b')).select('b').by('code'), "g.V().match(__.as('a').has('code','AUS'),__.as('a').out('route').as('b')).select('b').by('code')"],
+ // #30
+ [g.V().has('test-using-keyword-as-property','repeat'), "g.V().has('test-using-keyword-as-property','repeat')"],
+ // #31
+ [g.addE('test').to(__.V('4')), "g.addE('test').to(__.V('4'))"],
+ // #32
+ [g.V().values('runways').max(), 'g.V().values(\'runways\').max()'],
+ // #33
+ [g.V().values('runways').min(), 'g.V().values(\'runways\').min()'],
+ // #34
+ [g.V().values('runways').sum(), 'g.V().values(\'runways\').sum()'],
+ // #35
+ [g.V().values('runways').mean(), 'g.V().values(\'runways\').mean()'],
+ // #36
+ [g.withSack(0).V('3','5').sack(Operator.sum).by('runways').sack(), "g.withSack(0).V('3','5').sack(Operator.sum).by('runways').sack()"],
+ // #37
+ [g.inject(3,4,5), 'g.inject(3,4,5)'],
+ // #38
+ [g.inject([3,4,5]), 'g.inject([3,4,5])'],
+ // #39
+ [g.inject(3,4,5).count(), 'g.inject(3,4,5).count()'],
+ // #40
+ [g.V().has('runways',P.gt(5)).count(), "g.V().has('runways',gt(5)).count()"],
+ // #41
+ [g.V().has('runways',P.lte(5.3)).count(), "g.V().has('runways',lte(5.3)).count()"],
+ // #42
+ [g.V().has('code',P.within([123,124])), "g.V().has('code',within([123,124]))"],
+ // #43
+ [g.V().has('code',P.within([123,'abc'])), "g.V().has('code',within([123,'abc']))"],
+ // #44
+ [g.V().has('code',P.within(['abc',123])), "g.V().has('code',within(['abc',123]))"],
+ // #45
+ [g.V().has('code',P.within(['abc','xyz'])), "g.V().has('code',within(['abc','xyz']))"],
+ // #46
+ [g.V().has('region',P.within(['US-TX','US-GA'])), "g.V().has('region',within(['US-TX','US-GA']))"],
+ // #47
+ [g.V().and(__.has('runways',P.gt(5)),__.has('region','US-TX')), "g.V().and(__.has('runways',gt(5)),__.has('region','US-TX'))"],
+ // #48
+ [g.V().union(__.has('runways',P.gt(5)),__.has('region','US-TX')), "g.V().union(__.has('runways',gt(5)),__.has('region','US-TX'))"],
+ // #49
+ [g.V('3').choose(__.values('runways').is(3),__.constant('three'),__.constant('not three')), "g.V('3').choose(__.values('runways').is(3),__.constant('three'),__.constant('not three'))"],
+ // #50
+ [g.V('3').choose(__.out().count()).option(0,__.constant('none')).option(1,__.constant('one')).option(2,__.constant('two')), "g.V('3').choose(__.out().count()).option(0,__.constant('none')).option(1,__.constant('one')).option(2,__.constant('two'))"],
+ // #51
+ [g.V('3').choose(__.out().count()).option(1.5,__.constant('one and a half')), "g.V('3').choose(__.out().count()).option(1.5,__.constant('one and a half'))"],
+ // #52
+ [g.V().repeat(__.out()).until(__.or(__.loops().is(3),__.has('code','AGR'))).count(), "g.V().repeat(__.out()).until(__.or(__.loops().is(3),__.has('code','AGR'))).count()"],
+ // #53
+ [g.V().group().by('continent').by(__.count()).order(Scope.local).by(Column.values), "g.V().group().by('continent').by(__.count()).order(Scope.local).by(Column.values)"],
+ // #54
+ [g.V('3').as('a').out('route').as('a').select(Pop.all,'a'), "g.V('3').as('a').out('route').as('a').select(Pop.all,'a')"],
+ // #55
+ [g.addV('test').property(Cardinality.set,'p1',10), "g.addV('test').property(Cardinality.set,'p1',10)"],
+ // #56
+ [g.addV('test').property(Cardinality.list,'p1',10), "g.addV('test').property(Cardinality.list,'p1',10)"],
+ // #57
+ [g.addV('test').property(Cardinality.single,'p1',10), "g.addV('test').property(Cardinality.single,'p1',10)"],
+ // #58
+ [g.V().order().by(T.label), 'g.V().order().by(T.label)'],
+ // #59
+ [g.V().range(1,5), 'g.V().range(1,5)'],
+ // #60
+ [g.addV('test').property('p1',123), "g.addV('test').property('p1',123)"],
+ // #61
+ [g.addV('test').property('date',new Date('2021-02-01T09:30:00.000Z')), `g.addV('test').property('date',datetime("2021-02-01T09:30:00.000Z"))`],
+ // #62
+ [g.addV('test').property('date',new Date('2021-02-01T00:00:00.000Z')), `g.addV('test').property('date',datetime("2021-02-01T00:00:00.000Z"))`],
+ // #63
+ [g.addE('route').from_(__.V('1')).to(__.V('2')), "g.addE('route').from(__.V('1')).to(__.V('2'))"],
+ // #64
+ [g.withSideEffect('a',[1,2]).V().values('runways').where(P.within('a')), "g.withSideEffect('a',[1,2]).V().values('runways').where(within(['a']))"],
+ // #65
+ [g.withSideEffect('a',1).V().values('runways').where(P.within('a')), "g.withSideEffect('a',1).V().values('runways').where(within(['a']))"],
+ // #66
+ [g.withSideEffect('a','abc').V().values('runways').where(P.within('a')), "g.withSideEffect('a','abc').V().values('runways').where(within(['a']))"],
+ // #67
+ [g.V().hasLabel('airport').limit(5).values('code').fold().index(), "g.V().hasLabel('airport').limit(5).values('code').fold().index()"],
+ // #68
+ [g.V().hasLabel('airport').timeLimit(1000).count(), "g.V().hasLabel('airport').timeLimit(1000).count()"],
+ // #69
+ [g.V().where(__.values('elev').is(P.gt(14000))), "g.V().where(__.values('elev').is(gt(14000)))"],
+ // #70
+ [g.V().where(__.out().count().is(P.gt(200))).values('code'), "g.V().where(__.out().count().is(gt(200))).values('code')"],
+ // #71
+ [g.V().filter(__.has('region','US-TX')).count(), "g.V().filter(__.has('region','US-TX')).count()"],
+ // #72
+ [g.withSack(0).V('3').repeat(__.outE('route').sack(Operator.sum).by('dist').inV()).until(__.or(__.loops().is(2),__.sack().is(P.gt(500)))).local(__.union(__.path().by('code').by('dist'),__.sack()).fold()).limit(10), "g.withSack(0).V('3').repeat(__.outE('route').sack(Operator.sum).by('dist').inV()).until(__.or(__.loops().is(2),__.sack().is(gt(500)))).local(__.union(__.path().by('code').by('dist'),__.sack()).fold()).limit(10)"],
+ // #73
+ [g.addV().as('a').addV().as('b').addE('knows').from_('a').to('b'), "g.addV().as('a').addV().as('b').addE('knows').from('a').to('b')"],
+ // #74
+ [g.addV('Person').as('a').addV('Person').as('b').addE('knows').from_('a').to('b'), "g.addV('Person').as('a').addV('Person').as('b').addE('knows').from('a').to('b')"],
+ // #75
+ [g.V('3').project('Out','In').by(__.out().count()).by(__.in_().count()), "g.V('3').project('Out','In').by(__.out().count()).by(__.in().count())"],
+ // #76
+ [g.V('3').out('route').aggregate('x').where(P.within('x')).path().by('code'), "g.V('3').out('route').aggregate('x').where(within(['x'])).path().by('code')"],
+ // #77
+ [g.V().has('date',new Date('2021-02-22T00:00:00.000Z')), `g.V().has('date',datetime("2021-02-22T00:00:00.000Z"))`],
+ // #78
+ [g.V().has('date',P.within([new Date('2021-01-01T00:00:00.000Z'),new Date('2021-02-22T00:00:00.000Z')])), `g.V().has('date',within([datetime("2021-01-01T00:00:00.000Z"),datetime("2021-02-22T00:00:00.000Z")]))`],
+ // #79
+ [g.V().has('date',P.between(new Date('2021-01-01T00:00:00.000Z'),new Date('2021-02-22T00:00:00.000Z'))), `g.V().has('date',between(datetime("2021-01-01T00:00:00.000Z"),datetime("2021-02-22T00:00:00.000Z")))`],
+ // #80
+ [g.V().has('date',P.inside(new Date('2021-01-01T00:00:00.000Z'),new Date('2021-02-22T00:00:00.000Z'))), `g.V().has('date',inside(datetime("2021-01-01T00:00:00.000Z"),datetime("2021-02-22T00:00:00.000Z")))`],
+ // #81
+ [g.V().has('date',P.gt(new Date('2021-01-01T00:00:00.000Z'))), `g.V().has('date',gt(datetime("2021-01-01T00:00:00.000Z")))`],
+ // #82
+ [g.V().has('runways',P.between(3,5)), "g.V().has('runways',between(3,5))"],
+ // #83
+ [g.V().has('runways',P.inside(3,5)), "g.V().has('runways',inside(3,5))"],
+ // #84
+ [g.V('3').outE().elementMap(), "g.V('3').outE().elementMap()"],
+ // #85
+ [g.V('3').valueMap().by(__.unfold()), "g.V('3').valueMap().by(__.unfold())"],
+ // #86
+ [g.V('44').valueMap().with_(WithOptions.tokens,WithOptions.labels), "g.V('44').valueMap().with('~tinkerpop.valueMap.tokens',2)"],
+ // #87
+ [g.V('44').valueMap().with_(WithOptions.tokens), "g.V('44').valueMap().with('~tinkerpop.valueMap.tokens')"],
+ // #88
+ [g.withStrategies(new ReadOnlyStrategy()).addV('test'), "g.withStrategies(ReadOnlyStrategy).addV('test')"],
+ // #89
+ [g.withStrategies(new SubgraphStrategy({vertices: __.has('region','US-TX'), edges: __.hasLabel('route')})).V().count(), "g.withStrategies(new SubgraphStrategy(vertices:__.has('region','US-TX'),edges:__.hasLabel('route'))).V().count()"],
+ // #90
+ [g.withStrategies(new SubgraphStrategy({vertexProperties: __.hasNot('runways')})).V().count(), "g.withStrategies(new SubgraphStrategy(vertexProperties:__.hasNot('runways'))).V().count()"],
+ // #91
+ [g.withStrategies(new SubgraphStrategy({vertices: __.has('region','US-TX'), vertexProperties: __.hasNot('runways')})).V().count(), "g.withStrategies(new SubgraphStrategy(vertices:__.has('region','US-TX'),vertexProperties:__.hasNot('runways'))).V().count()"],
+ // #92
+ [g.withStrategies(new ReadOnlyStrategy(), new SubgraphStrategy({vertices: __.has('region','US-TX'), edges: __.hasLabel('route')})).V().count(), "g.withStrategies(ReadOnlyStrategy,new SubgraphStrategy(vertices:__.has('region','US-TX'),edges:__.hasLabel('route'))).V().count()"],
+ // #93
+ [g.withStrategies(new ReadOnlyStrategy(), new SubgraphStrategy({vertices: __.has('region','US-TX')})).V().count(), "g.withStrategies(ReadOnlyStrategy,new SubgraphStrategy(vertices:__.has('region','US-TX'))).V().count()"],
+ // #94 - OptionsStrategy extracted, not serialized
+ [g.with_('evaluationTimeout',500).V().count(), 'g.V().count()'],
+ // #95 - OptionsStrategy extracted, not serialized
+ [g.withStrategies(new OptionsStrategy({evaluationTimeout: 500})).V().count(), 'g.V().count()'],
+ // #96
+ [g.withStrategies(new PartitionStrategy({partitionKey: '_partition', writePartition: 'a', readPartitions: ['a','b']})).addV('test'), "g.withStrategies(new PartitionStrategy(partitionKey:'_partition',writePartition:'a',readPartitions:['a','b'])).addV('test')"],
+ // #97
+ [g.withComputer().V().shortestPath().with_('~tinkerpop.shortestPath.target',__.has('name','peter')), "g.withStrategies(VertexProgramStrategy).V().shortestPath().with('~tinkerpop.shortestPath.target',__.has('name','peter'))"],
+ // #98
+ [g.V().coalesce(__.E(),__.addE('person')), "g.V().coalesce(__.E(),__.addE('person'))"],
+ // #99
+ [g.inject(1).E(), 'g.inject(1).E()'],
+ // #100
+ [g.V().has('name',TextP.startingWith('foo')), "g.V().has('name',startingWith('foo'))"],
+ // #101
+ [g.V().has('name',TextP.endingWith('foo')), "g.V().has('name',endingWith('foo'))"],
+ // #102
+ [g.V().has('p1',null), "g.V().has('p1',null)"],
+ // #103
+ [g.V(new Vertex(0,'person')), 'g.V(0)'],
+ // #104 - Map with enum key
+ [g.inject(new Map([[T.id, 0], [T.label, 'person'], ['name', 'stephen'], ['age', 32]])), "g.inject([(T.id):0,(T.label):'person','name':'stephen','age':32])"],
+ // #105 - chained or predicates
+ [g.V().has('age',P.gt(5).or(P.lt(2)).or(P.eq(3))), "g.V().has('age',gt(5).or(lt(2)).or(eq(3)))"],
+ // #106 - complex nested and/or predicates
+ [g.V().has('age',P.gt(5).and(P.lt(10)).or(P.eq(15))), "g.V().has('age',gt(5).and(lt(10)).or(eq(15)))"],
+ // #107
+ [g.inject(new Set(['a'])), "g.inject({'a'})"],
+ // #108
+ [g.mergeV(null), 'g.mergeV(null)'],
+ // #109
+ [g.mergeE(null), 'g.mergeE(null)'],
+ // #110 - double quote in string
+ [g.addV('"test"'), "g.addV('\\\"test\\\"')"],
+ // #111 - mixed quotes
+ [g.addV("t'\"est"), "g.addV('t\\'\\\"est')"],
+ // #112 - newline in string
+ [g.addV('hello\nworld'), "g.addV('hello\\nworld')"],
+ // #113 - tab in string
+ [g.addV('hello\tworld'), "g.addV('hello\\tworld')"],
+ // #114 - carriage return in string
+ [g.inject('a\rb'), "g.inject('a\\rb')"],
+ // #115 - backspace in string
+ [g.inject('a\bb'), "g.inject('a\\bb')"],
+ // #116 - form feed in string
+ [g.inject('a\fb'), "g.inject('a\\fb')"],
+ // #117 - null char in string
+ [g.inject('a\x00b'), "g.inject('a\\u0000b')"],
+ // #118 - datetime with non-zero milliseconds
+ [g.inject(new Date('2018-03-21T08:35:44.741Z')), 'g.inject(datetime("2018-03-21T08:35:44.741Z"))'],
+ // #119 - withoutStrategies
+ [g.withoutStrategies(ReadOnlyStrategy).V(), 'g.withoutStrategies(ReadOnlyStrategy).V()'],
+ // #120 - SeedStrategy
+ [g.withStrategies(new SeedStrategy({seed: 999999})).V(), 'g.withStrategies(new SeedStrategy(seed:999999)).V()'],
+ // #121 - P.within with empty list
+ [g.V().has('code',P.within([])), "g.V().has('code',within([]))"],
+ // #122 - P.not
+ [g.V().has('age',P.not(P.eq(5))), "g.V().has('age',not(eq(5)))"],
+ // #123 - Direction aliases from_ and to mapped to OUT and IN
+ [g.V().to(direction.from_, 'knows').to(direction.in, 'created'),
+ "g.V().to(Direction.OUT,'knows').to(Direction.IN,'created')"],
+ // #124 - from_/to with Vertex ID extraction
+ [g.addE('knows').from_(new Vertex(1, 'person')).to(new Vertex(2, 'person')),
+ "g.addE('knows').from(1).to(2)"],
+ // #125 - mid-traversal V() with Vertex ID extraction
+ [g.inject('foo').V(1, new Vertex(2, 'person')),
+ "g.inject('foo').V(1,2)"],
+ // #126 - mergeE with Vertex ID extraction in Map (source step)
+ [g.mergeE(new Map([['label', 'knows'], [direction.out, new Vertex(1, 'person')], [direction.in, new Vertex(2, 'person')]])),
+ "g.mergeE(['label':'knows',(Direction.OUT):1,(Direction.IN):2])"],
+ // #127 - mergeE with Vertex ID extraction in Map (mid-traversal)
+ [g.inject('foo').mergeE(new Map([['label', 'knows'], [direction.out, new Vertex(1, 'person')], [direction.in, new Vertex(2, 'person')]])),
+ "g.inject('foo').mergeE(['label':'knows',(Direction.OUT):1,(Direction.IN):2])"],
+ ];
+
+ tests.forEach(([traversal, expected], index) => {
+ it(`test #${index}: ${expected}`, function () {
+ assert.strictEqual(traversal.getGremlinLang().getGremlin(), expected);
+ });
+ });
+ });
+
+ describe('JS-specific tests', function () {
+ it('should handle Long values', function () {
+ assert.strictEqual(g.V(new Long('9007199254740993')).getGremlinLang().getGremlin(), 'g.V(9007199254740993L)');
+ });
+
+ it('should handle NaN', function () {
+ assert.strictEqual(g.inject(NaN).getGremlinLang().getGremlin(), 'g.inject(NaN)');
+ });
+
+ it('should handle Infinity', function () {
+ assert.strictEqual(g.inject(Infinity).getGremlinLang().getGremlin(), 'g.inject(+Infinity)');
+ });
+
+ it('should handle -Infinity', function () {
+ assert.strictEqual(g.inject(-Infinity).getGremlinLang().getGremlin(), 'g.inject(-Infinity)');
+ });
+
+ it('source operations should not mutate original g', function () {
+ const g2 = g.withSack(0);
+ assert.strictEqual(g.V().getGremlinLang().getGremlin(), 'g.V()');
+ assert.strictEqual(g2.V().getGremlinLang().getGremlin(), 'g.withSack(0).V()');
+ });
+
+ it('should handle clone isolation', function () {
+ const t1 = g.V().has('name','josh');
+ const t2 = t1.clone().out('created');
+ assert.strictEqual(t1.getGremlinLang().getGremlin(), "g.V().has('name','josh')");
+ assert.strictEqual(t2.getGremlinLang().getGremlin(), "g.V().has('name','josh').out('created')");
+ });
+
+ it('should handle anonymous traversal prefix', function () {
+ const t = __.out('knows');
+ assert.strictEqual(t.getGremlinLang().getGremlin('__'), "__.out('knows')");
+ });
+
+ it('should handle OptionsStrategy extraction', function () {
+ const t = g.with_('evaluationTimeout', 500).V().count();
+ assert.strictEqual(t.getGremlinLang().getGremlin(), 'g.V().count()');
+ assert.strictEqual(t.getGremlinLang().getOptionsStrategies().length, 1);
+ });
+
+ it('should handle empty Set', function () {
+ assert.strictEqual(g.inject(new Set()).getGremlinLang().getGremlin(), 'g.inject({})');
+ });
+
+ it('should handle empty Map', function () {
+ assert.strictEqual(g.inject(new Map()).getGremlinLang().getGremlin(), 'g.inject([:])');
+ });
+
+ it('should handle inject with array', function () {
+ assert.strictEqual(g.inject([3,4,5]).getGremlinLang().getGremlin(), 'g.inject([3,4,5])');
+ });
+
+ it('should handle iterate/discard', function () {
+ const t = g.V().count();
+ t.iterate();
+ assert.strictEqual(t.getGremlinLang().getGremlin(), 'g.V().count().discard()');
+ });
+
+ it('should handle CardinalityValue.list', function () {
+ assert.strictEqual(
+ g.inject(new Map([['age', CardinalityValue.list(33)]])).getGremlinLang().getGremlin(),
+ "g.inject(['age':Cardinality.list(33)])"
+ );
+ });
+
+ it('should handle CardinalityValue.set', function () {
+ assert.strictEqual(
+ g.inject(new Map([['age', CardinalityValue.set(33)]])).getGremlinLang().getGremlin(),
+ "g.inject(['age':Cardinality.set(33)])"
+ );
+ });
+
+ it('should handle CardinalityValue.single', function () {
+ assert.strictEqual(
+ g.inject(new Map([['age', CardinalityValue.single(33)]])).getGremlinLang().getGremlin(),
+ "g.inject(['age':Cardinality.single(33)])"
+ );
+ });
+ });
+});
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js
deleted file mode 100644
index 1488328768..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator-test.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-import assert from 'assert';
-import { Graph } from '../../lib/structure/graph.js';
-import { order, P, TextP } from '../../lib/process/traversal.js';
-import Translator from '../../lib/process/translator.js';
-import { statics } from '../../lib/process/graph-traversal.js';
-const __ = statics;
-
-describe('Translator', function () {
-
- describe('#translate()', function () {
- it('should produce valid script representation from bytecode glv steps', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().out('created').getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().out(\'created\')');
- });
-
- it('should produce valid script representation from bytecode glv steps translating number and text correctly', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V(1).out('created').getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V(1).out(\'created\')');
- });
-
- it('should produce valid script representation from bytecode glv steps containing parameter bindings', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.addV({'name': 'Lilac'}).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.addV((\'name\', \'Lilac\'))');
- });
-
- it('should produce valid script representation from bytecode glv steps containing enum', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().order().by('age', order.shuffle).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().order().by(\'age\', shuffle)');
- });
-
- it('should produce valid script representation from bytecode glv steps containing a predicate', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().hasLabel('person').has('age', P.gt(30)).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().hasLabel(\'person\').has(\'age\', gt(30))');
- });
-
- it('should produce valid script representation from bytecode glv steps containing a string predicate', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().hasLabel('person').has('name', TextP.containing("foo")).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().hasLabel(\'person\').has(\'name\', containing(\'foo\'))');
- });
-
- it('should produce valid script representation from bytecode glv steps with child', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().filter(__.outE('created')).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().filter(__.outE(\'created\'))');
- });
-
- it('should produce valid script representation from bytecode glv steps with embedded child', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().filter(__.outE('created').filter(__.has('weight'))).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().filter(__.outE(\'created\').filter(__.has(\'weight\')))');
- });
-
- it('should produce valid script representation from bytecode glv steps with embedded children', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().or(__.has('name', 'a'), __.has('name', 'b')).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().or(__.has(\'name\', \'a\'), __.has(\'name\', \'b\'))');
- });
-
- it('should produce valid script representation from bytecode glv for boolean values', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().has('male', true).getBytecode());
- assert.ok(script);
- assert.strictEqual(script, 'g.V().has(\'male\', true)');
- });
-
- it('should produce valid script representation from a traversal object', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V().has('male', true));
- assert.ok(script);
- assert.strictEqual(script, 'g.V().has(\'male\', true)');
- });
-
- it('should produce valid script representation of array as step arg', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.V([1, 2, 3]));
- assert.ok(script);
- assert.strictEqual(script, 'g.V([1, 2, 3])');
- });
-
- it('should translate null', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.addV('test').property('empty', null));
- assert.ok(script);
- assert.strictEqual(script, 'g.addV(\'test\').property(\'empty\', null)');
- });
-
- it('should translate undefined to null', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.addV('test').property('empty', undefined));
- assert.ok(script);
- assert.strictEqual(script, 'g.addV(\'test\').property(\'empty\', null)');
- });
-
- it('should properly escape quotes in string literals', function () {
- const g = new Graph().traversal();
- const script = new Translator('g').translate(g.addV('test').property('quotes', "some \"quotes' in the middle."));
- assert.ok(script);
- assert.strictEqual(script, 'g.addV(\'test\').property(\'quotes\', \'some "quotes\\\' in the middle.\')');
- });
-
- it('should properly escape quotes in Object values', function () {
- const g = new Graph().traversal();
- const o = {key: "some \"quotes' in the middle."}
- const script = new Translator('g').translate(g.inject(o));
- assert.ok(script);
- assert.strictEqual(script, 'g.inject((\'key\', \'some "quotes\\\' in the middle.\'))');
- });
- });
-});
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/traversal-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/traversal-test.js
index f1b96d66e7..2e9c866a9f 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/traversal-test.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/traversal-test.js
@@ -28,69 +28,12 @@ import anon from '../../lib/process/anonymous-traversal.js';
import { P, order, direction, Traverser, Traversal } from '../../lib/process/traversal.js';
import { statics } from '../../lib/process/graph-traversal.js';
const V = statics.V;
-import Bytecode from '../../lib/process/bytecode.js';
+
import { TraversalStrategies } from '../../lib/process/traversal-strategy.js';
import { RemoteConnection } from '../../lib/driver/remote-connection.js';
describe('Traversal', function () {
- describe('#getByteCode()', function () {
- it('should add steps for with a string parameter', function () {
- const g = anon.traversal().with_(new Graph());
- const bytecode = g.V().out('created').getBytecode();
- assert.ok(bytecode);
- assert.strictEqual(bytecode.sourceInstructions.length, 0);
- assert.strictEqual(bytecode.stepInstructions.length, 2);
- assert.strictEqual(bytecode.stepInstructions[0][0], 'V');
- assert.strictEqual(bytecode.stepInstructions[1][0], 'out');
- assert.strictEqual(bytecode.stepInstructions[1][1], 'created');
- });
-
- it('should add steps with an enum value', function () {
- const g = anon.traversal().with_(new Graph());
- const bytecode = g.V().order().by('age', order.desc).getBytecode();
- assert.ok(bytecode);
- assert.strictEqual(bytecode.sourceInstructions.length, 0);
- assert.strictEqual(bytecode.stepInstructions.length, 3);
- assert.strictEqual(bytecode.stepInstructions[0][0], 'V');
- assert.strictEqual(bytecode.stepInstructions[1][0], 'order');
- assert.strictEqual(bytecode.stepInstructions[2][0], 'by');
- assert.strictEqual(bytecode.stepInstructions[2][1], 'age');
- assert.strictEqual(typeof bytecode.stepInstructions[2][2], 'object');
- assert.strictEqual(bytecode.stepInstructions[2][2].typeName, 'Order');
- assert.strictEqual(bytecode.stepInstructions[2][2].elementName, 'desc');
- });
-
- it('should add steps with Direction aliases from_ and to properly mapped to OUT and IN', function () {
- const g = anon.traversal().with_(new Graph());
- const bytecode = g.V().to(direction.from_, 'knows').to(direction.in, 'created').getBytecode();
- assert.ok(bytecode);
- assert.strictEqual(bytecode.sourceInstructions.length, 0);
- assert.strictEqual(bytecode.stepInstructions.length, 3);
- assert.strictEqual(bytecode.stepInstructions[0][0], 'V');
- assert.strictEqual(bytecode.stepInstructions[1][0], 'to');
- assert.strictEqual(typeof bytecode.stepInstructions[1][1], 'object');
- assert.strictEqual(bytecode.stepInstructions[1][1].typeName, 'Direction');
- assert.strictEqual(bytecode.stepInstructions[1][1].elementName, 'OUT');
- assert.strictEqual(bytecode.stepInstructions[1][2], 'knows');
- assert.strictEqual(bytecode.stepInstructions[2][1].typeName, 'Direction');
- assert.strictEqual(bytecode.stepInstructions[2][1].elementName, 'IN');
- assert.strictEqual(bytecode.stepInstructions[2][2], 'created');
- });
-
- it('should configure OptionStrategy for with_()', function () {
- const g = new Graph().traversal();
- const bytecode = g.with_('x','test').with_('y').V().getBytecode();
- assert.ok(bytecode);
- assert.strictEqual(bytecode.sourceInstructions.length, 1);
- assert.strictEqual(bytecode.sourceInstructions[0][0], 'withStrategies');
- const conf = bytecode.sourceInstructions[0][1].configuration;
- assert.strictEqual(conf.x, 'test');
- assert.strictEqual(conf.y, true);
- assert.strictEqual(bytecode.stepInstructions.length, 1);
- assert.strictEqual(bytecode.stepInstructions[0][0], 'V');
- });
- });
describe('#next()', function () {
it('should apply the strategies and return a Promise with the iterator item', function () {
@@ -228,7 +171,7 @@ describe('Traversal', function () {
};
const strategies = new TraversalStrategies();
strategies.addStrategy(strategyMock);
- const traversal = new Traversal(null, strategies, new Bytecode());
+ const traversal = new Traversal(null, strategies);
return traversal.iterate().then(() => {
assert.strictEqual(applied, true);
});
@@ -241,11 +184,11 @@ describe('Traversal', function () {
});
it('convert to string representation with P.within', function () {
- assert.strictEqual(P.within('a', 'b').toString(), 'within(\'a\',\'b\')');
+ assert.strictEqual(P.within('a', 'b').toString(), "within(['a', 'b'])");
});
it('convert to string representation with P.within array', function () {
- assert.strictEqual(P.within(['a', 'b']).toString(), 'within(\'a\',\'b\')');
+ assert.strictEqual(P.within(['a', 'b']).toString(), "within(['a', 'b'])");
});
});
@@ -306,67 +249,7 @@ describe('Traversal', function () {
});
});
- describe('#shouldExtractIdFromVertex()', function () {
- const g = anon.traversal().with_(new Graph());
- it('should extract ID from Vertex objects for V()', function () {
- // Test basic V() step with mixed ID types
- const vStart = g.V(1, new Vertex(2, 'person'));
- const vStartBytecode = vStart.getBytecode();
- assert.strictEqual(vStartBytecode.stepInstructions[0][0], 'V');
- assert.strictEqual(vStartBytecode.stepInstructions[0][1], 1);
- assert.strictEqual(vStartBytecode.stepInstructions[0][2], 2); // ID should be extracted from Vertex
-
- // Test V() step in the middle of a traversal
- const vMid = g.inject('foo').V(1, new Vertex(2, 'person'));
- const vMidBytecode = vMid.getBytecode();
- assert.strictEqual(vMidBytecode.stepInstructions[0][0], 'inject');
- assert.strictEqual(vMidBytecode.stepInstructions[0][1], 'foo');
- assert.strictEqual(vMidBytecode.stepInstructions[1][0], 'V');
- assert.strictEqual(vMidBytecode.stepInstructions[1][1], 1);
- assert.strictEqual(vMidBytecode.stepInstructions[1][2], 2); // ID should be extracted from Vertex
- });
- it('should extract ID from Vertex objects for from()/to()', function () {
- // Test edge creation with from/to vertices
- const fromTo = g.addE('Edge').from_(new Vertex(1, 'person')).to(new Vertex(2, 'person'));
- const fromToBytecode = fromTo.getBytecode();
- assert.strictEqual(fromToBytecode.stepInstructions[0][0], 'addE');
- assert.strictEqual(fromToBytecode.stepInstructions[0][1], 'Edge');
- assert.strictEqual(fromToBytecode.stepInstructions[1][0], 'from');
- assert.strictEqual(fromToBytecode.stepInstructions[1][1], 1); // ID should be extracted from Vertex
- assert.strictEqual(fromToBytecode.stepInstructions[2][0], 'to');
- assert.strictEqual(fromToBytecode.stepInstructions[2][1], 2); // ID should be extracted from Vertex
- });
- it('should extract ID from Vertex objects for mergeE()', function () {
- // Test mergeE() with Vertex in map
- const mergeMap = new Map();
- mergeMap.set('label', 'knows');
- mergeMap.set(direction.out, new Vertex(1, 'person'));
- mergeMap.set(direction.in, new Vertex(2, 'person'));
-
- const mergeEStart = g.mergeE(mergeMap);
- const mergeEStartBytecode = mergeEStart.getBytecode();
- assert.strictEqual(mergeEStartBytecode.stepInstructions[0][0], 'mergeE');
-
- // Check that the map contains extracted IDs
- const mergeMapArg = mergeEStartBytecode.stepInstructions[0][1];
- assert.strictEqual(mergeMapArg.get('label'), 'knows');
- assert.strictEqual(mergeMapArg.get(direction.out), 1); // ID should be extracted from Vertex
- assert.strictEqual(mergeMapArg.get(direction.in), 2); // ID should be extracted from Vertex
-
- // Test mergeE() in the middle of a traversal
- const mergeEMid = g.inject('foo').mergeE(mergeMap);
- const mergeEMidBytecode = mergeEMid.getBytecode();
- assert.strictEqual(mergeEMidBytecode.stepInstructions[0][0], 'inject');
- assert.strictEqual(mergeEMidBytecode.stepInstructions[0][1], 'foo');
- assert.strictEqual(mergeEMidBytecode.stepInstructions[1][0], 'mergeE');
- // Check that the map contains extracted IDs
- const mergeMapArg2 = mergeEMidBytecode.stepInstructions[1][1];
- assert.strictEqual(mergeMapArg2.get('label'), 'knows');
- assert.strictEqual(mergeMapArg2.get(direction.out), 1); // ID should be extracted from Vertex
- assert.strictEqual(mergeMapArg2.get(direction.in), 2); // ID should be extracted from Vertex
- });
- });
});
class MockRemoteConnection extends RemoteConnection {
@@ -379,7 +262,7 @@ class MockRemoteConnection extends RemoteConnection {
return this._bound;
}
- submit(bytecode) {
+ submit(gremlinLang) {
return Promise.resolve(undefined);
}