UNPKG

gremlin

Version:

JavaScript Gremlin Language Variant

556 lines (478 loc) 16.2 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: structure/io/type-serializers.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: structure/io/type-serializers.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/* * 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 */ 'use strict'; const t = require('../../process/traversal'); const ts = require('../../process/traversal-strategy'); const Bytecode = require('../../process/bytecode'); const g = require('../graph'); const utils = require('../../utils'); const valueKey = '@value'; const typeKey = '@type'; /** * @abstract */ class TypeSerializer { serialize() { throw new Error('serialize() method not implemented for ' + this.constructor.name); } deserialize() { throw new Error('deserialize() method not implemented for ' + this.constructor.name); } canBeUsedFor() { throw new Error('canBeUsedFor() method not implemented for ' + this.constructor.name); } } class NumberSerializer extends TypeSerializer { serialize(item) { if (isNaN(item)) { return { [typeKey]: 'g:Double', [valueKey]: 'NaN', }; } else if (item === Number.POSITIVE_INFINITY) { return { [typeKey]: 'g:Double', [valueKey]: 'Infinity', }; } else if (item === Number.NEGATIVE_INFINITY) { return { [typeKey]: 'g:Double', [valueKey]: '-Infinity', }; } return item; } deserialize(obj) { const val = obj[valueKey]; if (val === 'NaN') { return NaN; } else if (val === 'Infinity') { return Number.POSITIVE_INFINITY; } else if (val === '-Infinity') { return Number.NEGATIVE_INFINITY; } return parseFloat(val); } canBeUsedFor(value) { return typeof value === 'number'; } } class DateSerializer extends TypeSerializer { serialize(item) { return { [typeKey]: 'g:Date', [valueKey]: item.getTime(), }; } deserialize(obj) { return new Date(obj[valueKey]); } canBeUsedFor(value) { return value instanceof Date; } } class LongSerializer extends TypeSerializer { serialize(item) { return { [typeKey]: 'g:Int64', [valueKey]: item.value, }; } canBeUsedFor(value) { return value instanceof utils.Long; } } class BytecodeSerializer extends TypeSerializer { serialize(item) { let bytecode = item; if (item instanceof t.Traversal) { bytecode = item.getBytecode(); } const result = {}; result[typeKey] = 'g:Bytecode'; const resultValue = (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; } _serializeInstructions(instructions) { if (instructions.length === 0) { return null; } const result = new Array(instructions.length); result[0] = instructions[0]; for (let i = 0; i &lt; instructions.length; i++) { result[i] = instructions[i].map((item) => this.writer.adaptObject(item)); } return result; } canBeUsedFor(value) { return value instanceof Bytecode || value instanceof t.Traversal; } } class PSerializer extends TypeSerializer { /** @param {P} item */ serialize(item) { const result = {}; result[typeKey] = 'g:P'; const resultValue = (result[valueKey] = { predicate: item.operator, }); if (item.other === undefined || item.other === null) { resultValue['value'] = this.writer.adaptObject(item.value); } else { resultValue['value'] = [this.writer.adaptObject(item.value), this.writer.adaptObject(item.other)]; } return result; } canBeUsedFor(value) { return value instanceof t.P; } } class TextPSerializer extends TypeSerializer { /** @param {TextP} item */ serialize(item) { const result = {}; result[typeKey] = 'g:TextP'; const resultValue = (result[valueKey] = { predicate: item.operator, }); if (item.other === undefined || item.other === null) { resultValue['value'] = this.writer.adaptObject(item.value); } else { resultValue['value'] = [this.writer.adaptObject(item.value), this.writer.adaptObject(item.other)]; } return result; } canBeUsedFor(value) { return value instanceof t.TextP; } } class LambdaSerializer extends TypeSerializer { /** @param {Function} item */ serialize(item) { const lambdaDef = item(); // check if the language is specified otherwise assume gremlin-groovy. const returnIsString = typeof lambdaDef === 'string'; const script = returnIsString ? lambdaDef : lambdaDef[0]; const lang = returnIsString ? 'gremlin-groovy' : lambdaDef[1]; // detect argument count const argCount = lang === 'gremlin-groovy' &amp;&amp; script.includes('->') ? script.substring(0, script.indexOf('->')).includes(',') ? 2 : 1 : -1; return { [typeKey]: 'g:Lambda', [valueKey]: { arguments: argCount, language: lang, script: script, }, }; } canBeUsedFor(value) { return typeof value === 'function'; } } class EnumSerializer extends TypeSerializer { /** @param {EnumValue} item */ serialize(item) { return { [typeKey]: 'g:' + item.typeName, [valueKey]: item.elementName, }; } canBeUsedFor(value) { return value &amp;&amp; value.typeName &amp;&amp; value instanceof t.EnumValue; } } class TraverserSerializer extends TypeSerializer { /** @param {Traverser} item */ serialize(item) { return { [typeKey]: 'g:Traverser', [valueKey]: { value: this.writer.adaptObject(item.object), bulk: this.writer.adaptObject(item.bulk), }, }; } deserialize(obj) { const value = obj[valueKey]; return new t.Traverser(this.reader.read(value['value']), this.reader.read(value['bulk'])); } canBeUsedFor(value) { return value instanceof t.Traverser; } } class TraversalStrategySerializer extends TypeSerializer { /** @param {TraversalStrategy} item */ serialize(item) { const conf = {}; for (const k in item.configuration) { if (item.configuration.hasOwnProperty(k)) { conf[k] = this.writer.adaptObject(item.configuration[k]); } } return { [typeKey]: 'g:' + item.constructor.name, [valueKey]: conf, }; } canBeUsedFor(value) { return value instanceof ts.TraversalStrategy; } } class VertexSerializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; return new g.Vertex(this.reader.read(value['id']), value['label'], this.reader.read(value['properties'])); } /** @param {Vertex} item */ serialize(item) { return { [typeKey]: 'g:Vertex', [valueKey]: { id: this.writer.adaptObject(item.id), label: item.label, }, }; } canBeUsedFor(value) { return value instanceof g.Vertex; } } class VertexPropertySerializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; return new g.VertexProperty( this.reader.read(value['id']), value['label'], this.reader.read(value['value']), this.reader.read(value['properties']), ); } } class PropertySerializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; return new g.Property(value['key'], this.reader.read(value['value'])); } } class EdgeSerializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; return new g.Edge( this.reader.read(value['id']), new g.Vertex(this.reader.read(value['outV']), this.reader.read(value['outVLabel'])), value['label'], new g.Vertex(this.reader.read(value['inV']), this.reader.read(value['inVLabel'])), this.reader.read(value['properties']), ); } /** @param {Edge} item */ serialize(item) { return { [typeKey]: 'g:Edge', [valueKey]: { id: this.writer.adaptObject(item.id), label: item.label, outV: this.writer.adaptObject(item.outV.id), outVLabel: item.outV.label, inV: this.writer.adaptObject(item.inV.id), inVLabel: item.inV.label, }, }; } canBeUsedFor(value) { return value instanceof g.Edge; } } class PathSerializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; const objects = value['objects'].map((o) => this.reader.read(o)); return new g.Path(this.reader.read(value['labels']), objects); } } class Path3Serializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; return new g.Path(this.reader.read(value['labels']), this.reader.read(value['objects'])); } } class TSerializer extends TypeSerializer { deserialize(obj) { return t.t[obj[valueKey]]; } } class DirectionSerializer extends TypeSerializer { deserialize(obj) { return t.direction[obj[valueKey].toLowerCase()]; } } class ArraySerializer extends TypeSerializer { constructor(typeKey) { super(); this.typeKey = typeKey; } deserialize(obj) { const value = obj[valueKey]; if (!Array.isArray(value)) { throw new Error('Expected Array, obtained: ' + value); } return value.map((x) => this.reader.read(x)); } /** @param {Array} item */ serialize(item) { return { [typeKey]: this.typeKey, [valueKey]: item.map((x) => this.writer.adaptObject(x)), }; } canBeUsedFor(value) { return Array.isArray(value); } } class BulkSetSerializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; if (!Array.isArray(value)) { throw new Error('Expected Array, obtained: ' + value); } // coerce the BulkSet to List. if the bulk exceeds the int space then we can't coerce to List anyway, // so this query will be trouble. we'd need a legit BulkSet implementation here in js. this current // implementation is here to replicate the previous functionality that existed on the server side in // previous versions. let result = []; for (let ix = 0, iy = value.length; ix &lt; iy; ix += 2) { const pair = value.slice(ix, ix + 2); result = result.concat(Array(this.reader.read(pair[1])).fill(this.reader.read(pair[0]))); } return result; } } class MapSerializer extends TypeSerializer { deserialize(obj) { const value = obj[valueKey]; if (!Array.isArray(value)) { throw new Error('Expected Array, obtained: ' + value); } const result = new Map(); for (let i = 0; i &lt; value.length; i += 2) { result.set(this.reader.read(value[i]), this.reader.read(value[i + 1])); } return result; } /** @param {Map} map */ serialize(map) { const arr = []; map.forEach((v, k) => { arr.push(this.writer.adaptObject(k)); arr.push(this.writer.adaptObject(v)); }); return { [typeKey]: 'g:Map', [valueKey]: arr, }; } canBeUsedFor(value) { return value instanceof Map; } } class ListSerializer extends ArraySerializer { constructor() { super('g:List'); } } class SetSerializer extends ArraySerializer { constructor() { super('g:Set'); } } module.exports = { BulkSetSerializer, BytecodeSerializer, DateSerializer, DirectionSerializer, EdgeSerializer, EnumSerializer, LambdaSerializer, ListSerializer, LongSerializer, MapSerializer, NumberSerializer, Path3Serializer, PathSerializer, PropertySerializer, PSerializer, TextPSerializer, SetSerializer, TSerializer, TraverserSerializer, TraversalStrategySerializer, typeKey, valueKey, VertexPropertySerializer, VertexSerializer, }; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="AnonymousTraversalSource.html">AnonymousTraversalSource</a></li><li><a href="Authenticator.html">Authenticator</a></li><li><a href="Bytecode.html">Bytecode</a></li><li><a href="CardinalityValue.html">CardinalityValue</a></li><li><a href="Client.html">Client</a></li><li><a href="Connection.html">Connection</a></li><li><a href="DriverRemoteConnection.html">DriverRemoteConnection</a></li><li><a href="EdgeLabelVerificationStrategy.html">EdgeLabelVerificationStrategy</a></li><li><a href="Graph.html">Graph</a></li><li><a href="GraphSON2Reader.html">GraphSON2Reader</a></li><li><a href="GraphSON2Writer.html">GraphSON2Writer</a></li><li><a href="GraphSON3Reader.html">GraphSON3Reader</a></li><li><a href="GraphSON3Writer.html">GraphSON3Writer</a></li><li><a href="GraphTraversal.html">GraphTraversal</a></li><li><a href="GraphTraversalSource.html">GraphTraversalSource</a></li><li><a href="HaltedTraverserStrategy.html">HaltedTraverserStrategy</a></li><li><a href="MatchAlgorithmStrategy.html">MatchAlgorithmStrategy</a></li><li><a href="module.exports.html">exports</a></li><li><a href="P.html">P</a></li><li><a href="PartitionStrategy.html">PartitionStrategy</a></li><li><a href="Path.html">Path</a></li><li><a href="PlainTextSaslAuthenticator.html">PlainTextSaslAuthenticator</a></li><li><a href="ProductiveByStrategy.html">ProductiveByStrategy</a></li><li><a href="RemoteConnection.html">RemoteConnection</a></li><li><a href="RemoteStrategy.html">RemoteStrategy</a></li><li><a href="RemoteTraversal.html">RemoteTraversal</a></li><li><a href="ReservedKeysVerificationStrategy.html">ReservedKeysVerificationStrategy</a></li><li><a href="ResponseError.html">ResponseError</a></li><li><a href="ResultSet.html">ResultSet</a></li><li><a href="SaslAuthenticator.html">SaslAuthenticator</a></li><li><a href="SaslMechanismBase.html">SaslMechanismBase</a></li><li><a href="SaslMechanismPlain.html">SaslMechanismPlain</a></li><li><a href="SeedStrategy.html">SeedStrategy</a></li><li><a href="SubgraphStrategy.html">SubgraphStrategy</a></li><li><a href="TextP.html">TextP</a></li><li><a href="Transaction.html">Transaction</a></li><li><a href="Translator.html">Translator</a></li><li><a href="TraversalStrategies.html">TraversalStrategies</a></li><li><a href="TraversalStrategy.html">TraversalStrategy</a></li><li><a href="TypeSerializer.html">TypeSerializer</a></li></ul><h3>Global</h3><ul><li><a href="global.html#DataType">DataType</a></li><li><a href="global.html#statics">statics</a></li><li><a href="global.html#toArrayBuffer">toArrayBuffer</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 3.6.10</a> on Fri Aug 08 2025 09:56:42 GMT-0700 (Pacific Daylight Time) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>