Node JS version
This commit is contained in:
99
node_modules/cassandra-driver/lib/datastax/graph/complex-type-helper.js
generated
vendored
Normal file
99
node_modules/cassandra-driver/lib/datastax/graph/complex-type-helper.js
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const { GraphTypeWrapper, UdtGraphWrapper } = require('./wrappers');
|
||||
const types = require('../../types');
|
||||
const Encoder = require('../../encoder');
|
||||
const { dataTypes } = types;
|
||||
|
||||
function getTypeDefinitionByValue(value) {
|
||||
if (value instanceof types.Tuple) {
|
||||
return {
|
||||
'cqlType': 'tuple',
|
||||
'definition': value.elements.map(getTypeDefinitionByValue)
|
||||
};
|
||||
}
|
||||
|
||||
if (value instanceof Map) {
|
||||
// Try to guess the types of the key and value based on the first element
|
||||
const result = { 'cqlType': 'map' };
|
||||
if (value.size > 0) {
|
||||
const first = value.entries().next().value;
|
||||
result['definition'] = first.map(getTypeDefinitionByValue);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (value instanceof UdtGraphWrapper) {
|
||||
return getUdtTypeDefinitionByValue(value);
|
||||
}
|
||||
|
||||
let type;
|
||||
if (value instanceof GraphTypeWrapper) {
|
||||
type = value.typeInfo;
|
||||
} else {
|
||||
type = Encoder.guessDataType(value);
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getDefinitionByType(type);
|
||||
}
|
||||
|
||||
function getDefinitionByType(type) {
|
||||
if (type.code === dataTypes.udt) {
|
||||
return getUdtTypeDefinition(type.info);
|
||||
}
|
||||
|
||||
if (type.code === dataTypes.tuple || type.code === dataTypes.map) {
|
||||
return {
|
||||
'cqlType': types.getDataTypeNameByCode(type),
|
||||
'definition': type.info.map(getDefinitionByType)
|
||||
};
|
||||
}
|
||||
|
||||
if (type.code === dataTypes.list || type.code === dataTypes.set) {
|
||||
return {
|
||||
'cqlType': type.code === dataTypes.list ? 'list' : 'set',
|
||||
'definition': [ getDefinitionByType(type.info) ]
|
||||
};
|
||||
}
|
||||
|
||||
return { 'cqlType': types.getDataTypeNameByCode(type) };
|
||||
}
|
||||
|
||||
function getUdtTypeDefinition(udtInfo) {
|
||||
return {
|
||||
'cqlType': 'udt',
|
||||
'keyspace': udtInfo.keyspace,
|
||||
'name': udtInfo.name,
|
||||
'definition': udtInfo.fields.map(field =>
|
||||
// fieldName should be the first property serialized
|
||||
Object.assign({ 'fieldName': field.name }, getDefinitionByType(field.type))
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function getUdtTypeDefinitionByValue(wrappedValue) {
|
||||
return getUdtTypeDefinition(wrappedValue.udtInfo);
|
||||
}
|
||||
|
||||
module.exports = { getTypeDefinitionByValue, getUdtTypeDefinitionByValue };
|
362
node_modules/cassandra-driver/lib/datastax/graph/custom-type-serializers.js
generated
vendored
Normal file
362
node_modules/cassandra-driver/lib/datastax/graph/custom-type-serializers.js
generated
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const types = require('../../types');
|
||||
const utils = require('../../utils');
|
||||
const { getTypeDefinitionByValue, getUdtTypeDefinitionByValue } = require('./complex-type-helper');
|
||||
const { Point, Polygon, LineString } = require('../../geometry');
|
||||
const { Edge } = require('./structure');
|
||||
const { GraphTypeWrapper, UdtGraphWrapper } = require('./wrappers');
|
||||
const { Tuple, dataTypes } = types;
|
||||
|
||||
const typeKey = '@type';
|
||||
const valueKey = '@value';
|
||||
|
||||
class EdgeDeserializer {
|
||||
constructor() {
|
||||
this.key = 'g:Edge';
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
const value = obj[valueKey];
|
||||
return new Edge(this.reader.read(value['id']), this.reader.read(value['outV']), value['outVLabel'], value['label'], this.reader.read(value['inV']), value['inVLabel'], this.reader.read(value['properties']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses toString() instance method and fromString() static method to serialize and deserialize the value.
|
||||
* @abstract
|
||||
* @private
|
||||
*/
|
||||
class StringBasedTypeSerializer {
|
||||
|
||||
/**
|
||||
* Creates a new instance of the deserializer.
|
||||
* @param {String} key
|
||||
* @param {Function} targetType
|
||||
*/
|
||||
constructor(key, targetType) {
|
||||
if (!key) {
|
||||
throw new Error('Deserializer must provide a type key');
|
||||
}
|
||||
if (!targetType) {
|
||||
throw new Error('Deserializer must provide a target type');
|
||||
}
|
||||
this.key = key;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
let value = obj[valueKey];
|
||||
if (typeof value !== 'string') {
|
||||
value = value.toString();
|
||||
}
|
||||
return this.targetType.fromString(value);
|
||||
}
|
||||
|
||||
serialize(value) {
|
||||
return {
|
||||
[typeKey]: this.key,
|
||||
[valueKey]: value.toString()
|
||||
};
|
||||
}
|
||||
|
||||
canBeUsedFor(value) {
|
||||
return value instanceof this.targetType;
|
||||
}
|
||||
}
|
||||
|
||||
class UuidSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('g:UUID', types.Uuid);
|
||||
}
|
||||
}
|
||||
|
||||
class LongSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('g:Int64', types.Long);
|
||||
}
|
||||
}
|
||||
|
||||
class BigDecimalSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('gx:BigDecimal', types.BigDecimal);
|
||||
}
|
||||
}
|
||||
|
||||
class BigIntegerSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('gx:BigInteger', types.Integer);
|
||||
}
|
||||
}
|
||||
|
||||
class InetAddressSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('gx:InetAddress', types.InetAddress);
|
||||
}
|
||||
}
|
||||
|
||||
class LocalDateSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('gx:LocalDate', types.LocalDate);
|
||||
}
|
||||
}
|
||||
|
||||
class LocalTimeSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('gx:LocalTime', types.LocalTime);
|
||||
}
|
||||
}
|
||||
|
||||
class InstantSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('gx:Instant', Date);
|
||||
}
|
||||
|
||||
serialize(item) {
|
||||
return {
|
||||
[typeKey]: this.key,
|
||||
[valueKey]: item.toISOString()
|
||||
};
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
return new Date(obj[valueKey]);
|
||||
}
|
||||
}
|
||||
|
||||
class BlobSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('dse:Blob', Buffer);
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
return utils.allocBufferFromString(obj[valueKey], 'base64');
|
||||
}
|
||||
|
||||
serialize(item) {
|
||||
return {
|
||||
[typeKey]: this.key,
|
||||
[valueKey]: item.toString('base64')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class PointSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('dse:Point', Point);
|
||||
}
|
||||
}
|
||||
|
||||
class LineStringSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('dse:LineString', LineString);
|
||||
}
|
||||
}
|
||||
|
||||
class PolygonSerializer extends StringBasedTypeSerializer {
|
||||
constructor() {
|
||||
super('dse:Polygon', Polygon);
|
||||
}
|
||||
}
|
||||
|
||||
class TupleSerializer {
|
||||
constructor() {
|
||||
this.key = 'dse:Tuple';
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
// Skip definitions and go to the value
|
||||
const value = obj[valueKey]['value'];
|
||||
|
||||
if (!Array.isArray(value)) {
|
||||
throw new Error('Expected Array, obtained: ' + value);
|
||||
}
|
||||
|
||||
const result = [];
|
||||
|
||||
for (const element of value) {
|
||||
result.push(this.reader.read(element));
|
||||
}
|
||||
|
||||
return Tuple.fromArray(result);
|
||||
}
|
||||
|
||||
/** @param {Tuple} tuple */
|
||||
serialize(tuple) {
|
||||
const result = {
|
||||
'cqlType': 'tuple',
|
||||
'definition': tuple.elements.map(getTypeDefinitionByValue),
|
||||
'value': tuple.elements.map(e => this.writer.adaptObject(e))
|
||||
};
|
||||
|
||||
return {
|
||||
[typeKey]: this.key,
|
||||
[valueKey]: result
|
||||
};
|
||||
}
|
||||
|
||||
canBeUsedFor(value) {
|
||||
return value instanceof Tuple;
|
||||
}
|
||||
}
|
||||
|
||||
class DurationSerializer {
|
||||
constructor() {
|
||||
this.key = 'dse:Duration';
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
// Skip definitions and go to the value
|
||||
const value = obj[valueKey];
|
||||
|
||||
return new types.Duration(
|
||||
this.reader.read(value['months']), this.reader.read(value['days']), this.reader.read(value['nanos']));
|
||||
}
|
||||
|
||||
/** @param {Duration} value */
|
||||
serialize(value) {
|
||||
return {
|
||||
[typeKey]: this.key,
|
||||
[valueKey]: {
|
||||
'months': value['months'],
|
||||
'days': value['days'],
|
||||
'nanos': value['nanoseconds'],
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
canBeUsedFor(value) {
|
||||
return value instanceof types.Duration;
|
||||
}
|
||||
}
|
||||
|
||||
class UdtSerializer {
|
||||
constructor() {
|
||||
this.key = 'dse:UDT';
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
// Skip definitions and go to the value
|
||||
const valueRoot = obj[valueKey];
|
||||
const result = {};
|
||||
const value = valueRoot['value'];
|
||||
|
||||
valueRoot['definition'].forEach((definition, index) => {
|
||||
result[definition.fieldName] = this.reader.read(value[index]);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
serialize(udtWrapper) {
|
||||
const serializedValue = getUdtTypeDefinitionByValue(udtWrapper);
|
||||
// New properties can be added to the existing object without need to clone
|
||||
// as getTypeDefinition() returns a new object each time
|
||||
serializedValue['value'] = Object.entries(udtWrapper.value).map(([_, v]) => this.writer.adaptObject(v));
|
||||
|
||||
return {
|
||||
[typeKey]: this.key,
|
||||
[valueKey]: serializedValue
|
||||
};
|
||||
}
|
||||
|
||||
canBeUsedFor(value) {
|
||||
return value instanceof UdtGraphWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
class InternalSerializer {
|
||||
constructor(name, transformFn) {
|
||||
this._name = name;
|
||||
this._transformFn = transformFn || (x => x);
|
||||
}
|
||||
|
||||
serialize(item) {
|
||||
return {
|
||||
[typeKey]: this._name,
|
||||
[valueKey]: this._transformFn(item)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Associative array of graph type name by CQL type code, used by the type wrapper
|
||||
const graphSONSerializerByCqlType = {
|
||||
[dataTypes.int]: new InternalSerializer('g:Int32'),
|
||||
[dataTypes.bigint]: new InternalSerializer('g:Int64'),
|
||||
[dataTypes.double]: new InternalSerializer('g:Double'),
|
||||
[dataTypes.float]: new InternalSerializer('g:Float'),
|
||||
[dataTypes.timestamp]: new InternalSerializer('g:Timestamp', x => x.getTime())
|
||||
};
|
||||
|
||||
class GraphTypeWrapperSerializer {
|
||||
constructor() {
|
||||
// Use a fixed name that doesn't conflict with TinkerPop and DS Graph
|
||||
this.key = 'client:wrapper';
|
||||
}
|
||||
|
||||
serialize(wrappedValue) {
|
||||
const s = graphSONSerializerByCqlType[wrappedValue.typeInfo.code];
|
||||
|
||||
if (!s) {
|
||||
throw new Error(`No serializer found for wrapped value ${wrappedValue}`);
|
||||
}
|
||||
|
||||
return s.serialize(wrappedValue.value);
|
||||
}
|
||||
|
||||
canBeUsedFor(value) {
|
||||
return value instanceof GraphTypeWrapper;
|
||||
}
|
||||
}
|
||||
|
||||
const serializersArray = [
|
||||
EdgeDeserializer,
|
||||
UuidSerializer,
|
||||
LongSerializer,
|
||||
BigDecimalSerializer,
|
||||
BigIntegerSerializer,
|
||||
InetAddressSerializer,
|
||||
LocalDateSerializer,
|
||||
LocalTimeSerializer,
|
||||
InstantSerializer,
|
||||
BlobSerializer,
|
||||
PointSerializer,
|
||||
LineStringSerializer,
|
||||
PolygonSerializer,
|
||||
TupleSerializer,
|
||||
UdtSerializer,
|
||||
GraphTypeWrapperSerializer,
|
||||
DurationSerializer
|
||||
];
|
||||
|
||||
function getCustomSerializers() {
|
||||
const customSerializers = {};
|
||||
|
||||
serializersArray.forEach(sConstructor => {
|
||||
const instance = new sConstructor();
|
||||
if (!instance.key) {
|
||||
throw new TypeError(`Key for ${sConstructor} instance not set`);
|
||||
}
|
||||
|
||||
customSerializers[instance.key] = instance;
|
||||
});
|
||||
|
||||
return customSerializers;
|
||||
}
|
||||
|
||||
module.exports = getCustomSerializers;
|
280
node_modules/cassandra-driver/lib/datastax/graph/graph-executor.js
generated
vendored
Normal file
280
node_modules/cassandra-driver/lib/datastax/graph/graph-executor.js
generated
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const utils = require('../../utils');
|
||||
const policies = require('../../policies');
|
||||
const GraphResultSet = require('./result-set');
|
||||
const { GraphSON2Reader, GraphSON2Writer, GraphSON3Reader, GraphSON3Writer } = require('./graph-serializer');
|
||||
const getCustomTypeSerializers = require('./custom-type-serializers');
|
||||
const { GraphExecutionOptions, graphProtocol } = require('./options');
|
||||
|
||||
const graphLanguageGroovyString = 'gremlin-groovy';
|
||||
const graphEngineCore = 'Core';
|
||||
|
||||
const graphSON2Reader = new GraphSON2Reader({ serializers: getCustomTypeSerializers() });
|
||||
const graphSON2Writer = new GraphSON2Writer({ serializers: getCustomTypeSerializers() });
|
||||
const graphSON3Reader = new GraphSON3Reader({ serializers: getCustomTypeSerializers() });
|
||||
const graphSON3Writer = new GraphSON3Writer({ serializers: getCustomTypeSerializers() });
|
||||
|
||||
const rowParsers = new Map([
|
||||
[ graphProtocol.graphson2, getRowParser(graphSON2Reader) ],
|
||||
[ graphProtocol.graphson3, getRowParser(graphSON3Reader) ]
|
||||
]);
|
||||
|
||||
const defaultWriters = new Map([
|
||||
[ graphProtocol.graphson1, x => JSON.stringify(x) ],
|
||||
[ graphProtocol.graphson2, getDefaultWriter(graphSON2Writer) ],
|
||||
[ graphProtocol.graphson3, getDefaultWriter(graphSON3Writer) ]
|
||||
]);
|
||||
|
||||
/**
|
||||
* Internal class that contains the logic for executing a graph traversal.
|
||||
* @ignore
|
||||
*/
|
||||
class GraphExecutor {
|
||||
|
||||
/**
|
||||
* Creates a new instance of GraphExecutor.
|
||||
* @param {Client} client
|
||||
* @param {ClientOptions} rawOptions
|
||||
* @param {Function} handler
|
||||
*/
|
||||
constructor(client, rawOptions, handler) {
|
||||
this._client = client;
|
||||
this._handler = handler;
|
||||
|
||||
// Retrieve the retry policy for the default profile to determine if it was specified
|
||||
this._defaultProfileRetryPolicy = client.profileManager.getDefaultConfiguredRetryPolicy();
|
||||
|
||||
// Use graphBaseOptions as a way to gather all defaults that affect graph executions
|
||||
this._graphBaseOptions = utils.extend({
|
||||
executeAs: client.options.queryOptions.executeAs,
|
||||
language: graphLanguageGroovyString,
|
||||
source: 'g',
|
||||
readTimeout: 0,
|
||||
// As the default retry policy might retry non-idempotent queries
|
||||
// we should use default retry policy for all graph queries that does not retry
|
||||
retry: new policies.retry.FallthroughRetryPolicy()
|
||||
}, rawOptions.graphOptions, client.profileManager.getDefault().graphOptions);
|
||||
|
||||
if (this._graphBaseOptions.readTimeout === null) {
|
||||
this._graphBaseOptions.readTimeout = client.options.socketOptions.readTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the graph traversal.
|
||||
* @param {String|Object} query
|
||||
* @param {Object} parameters
|
||||
* @param {GraphQueryOptions} options
|
||||
*/
|
||||
async send(query, parameters, options) {
|
||||
if (Array.isArray(parameters)) {
|
||||
throw new TypeError('Parameters must be a Object instance as an associative array');
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
throw new TypeError('Query must be defined');
|
||||
}
|
||||
|
||||
const execOptions = new GraphExecutionOptions(
|
||||
options, this._client, this._graphBaseOptions, this._defaultProfileRetryPolicy);
|
||||
|
||||
if (execOptions.getGraphSource() === 'a') {
|
||||
const host = await this._getAnalyticsMaster();
|
||||
execOptions.setPreferredHost(host);
|
||||
}
|
||||
|
||||
// A query object that allows to plugin any executable thing
|
||||
const isQueryObject = typeof query === 'object' && query.graphLanguage && query.value && query.queryWriterFactory;
|
||||
|
||||
if (isQueryObject) {
|
||||
// Use the provided graph language to override the current
|
||||
execOptions.setGraphLanguage(query.graphLanguage);
|
||||
}
|
||||
|
||||
this._setGraphProtocol(execOptions);
|
||||
execOptions.setGraphPayload();
|
||||
parameters = GraphExecutor._buildGraphParameters(parameters, execOptions.getGraphSubProtocol());
|
||||
|
||||
if (typeof query !== 'string') {
|
||||
// Its a traversal that needs to be converted
|
||||
// Transforming the provided query into a traversal requires the protocol to be set first.
|
||||
// Query writer factory can be defined in the options or in the query object
|
||||
let queryWriter = execOptions.getQueryWriter();
|
||||
|
||||
if (isQueryObject) {
|
||||
queryWriter = query.queryWriterFactory(execOptions.getGraphSubProtocol());
|
||||
} else if (!queryWriter) {
|
||||
queryWriter = GraphExecutor._writerFactory(execOptions.getGraphSubProtocol());
|
||||
}
|
||||
|
||||
query = queryWriter(!isQueryObject ? query : query.value);
|
||||
}
|
||||
|
||||
return await this._executeGraphQuery(query, parameters, execOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the graph traversal.
|
||||
* @param {string} query
|
||||
* @param {object} parameters
|
||||
* @param {GraphExecutionOptions} execOptions
|
||||
* @returns {Promise<GraphResultSet>}
|
||||
* @private
|
||||
*/
|
||||
async _executeGraphQuery(query, parameters, execOptions) {
|
||||
const result = await this._handler.call(this._client, query, parameters, execOptions);
|
||||
|
||||
// Instances of rowParser transform Row instances into Traverser instances.
|
||||
// Traverser instance is an object with the following form { object: any, bulk: number }
|
||||
const rowParser = execOptions.getRowParser() || GraphExecutor._rowParserFactory(execOptions.getGraphSubProtocol());
|
||||
|
||||
return new GraphResultSet(result, rowParser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the RPC call to obtain the analytics master host.
|
||||
* @returns {Promise<Host|null>}
|
||||
* @private
|
||||
*/
|
||||
async _getAnalyticsMaster() {
|
||||
try {
|
||||
const result = await this._client.execute('CALL DseClientTool.getAnalyticsGraphServer()', utils.emptyArray);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
this._client.log('verbose',
|
||||
'Empty response querying graph analytics server, query will not be routed optimally');
|
||||
return null;
|
||||
}
|
||||
|
||||
const resultField = result.rows[0]['result'];
|
||||
if (!resultField || !resultField['location']) {
|
||||
this._client.log('verbose',
|
||||
'Unexpected response querying graph analytics server, query will not be routed optimally',
|
||||
result.rows[0]);
|
||||
return null;
|
||||
}
|
||||
|
||||
const hostName = resultField['location'].substr(0, resultField['location'].lastIndexOf(':'));
|
||||
const addressTranslator = this._client.options.policies.addressResolution;
|
||||
|
||||
return await new Promise(resolve => {
|
||||
addressTranslator.translate(hostName, this._client.options.protocolOptions.port, (endpoint) =>
|
||||
resolve(this._client.hosts.get(endpoint)));
|
||||
});
|
||||
} catch (err) {
|
||||
this._client.log('verbose', 'Error querying graph analytics server, query will not be routed optimally', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves what protocol should be used for decoding graph results for the given execution.
|
||||
*
|
||||
* <p>Resolution is done in the following manner if graphResults is not set:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>If graph name is set, and associated keyspace's graph engine is set to "Core", use {@link
|
||||
* graphProtocol#graphson3}.
|
||||
* <li>Else, if the graph language is not 'gremlin-groovy', use {@link graphProtocol#graphson2}
|
||||
* <li>Otherwise, use {@link graphProtocol#graphson1}
|
||||
* </ul>
|
||||
* @param {GraphExecutionOptions} execOptions
|
||||
*/
|
||||
_setGraphProtocol(execOptions) {
|
||||
let protocol = execOptions.getGraphSubProtocol();
|
||||
|
||||
if (protocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (execOptions.getGraphName()) {
|
||||
const keyspace = this._client.metadata.keyspaces[execOptions.getGraphName()];
|
||||
if (keyspace && keyspace.graphEngine === graphEngineCore) {
|
||||
protocol = graphProtocol.graphson3;
|
||||
}
|
||||
}
|
||||
|
||||
if (!protocol) {
|
||||
// Decide the minimal version supported by the graph language
|
||||
if (execOptions.getGraphLanguage() === graphLanguageGroovyString) {
|
||||
protocol = graphProtocol.graphson1;
|
||||
} else {
|
||||
protocol = graphProtocol.graphson2;
|
||||
}
|
||||
}
|
||||
|
||||
execOptions.setGraphSubProtocol(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only GraphSON1 parameters are supported.
|
||||
* @param {Array|function|null} parameters
|
||||
* @param {string} protocol
|
||||
* @returns {string[]|null}
|
||||
* @private
|
||||
*/
|
||||
static _buildGraphParameters(parameters, protocol) {
|
||||
if (!parameters || typeof parameters !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const queryWriter = GraphExecutor._writerFactory(protocol);
|
||||
|
||||
return [
|
||||
(protocol !== graphProtocol.graphson1 && protocol !== graphProtocol.graphson2)
|
||||
? queryWriter(new Map(Object.entries(parameters)))
|
||||
: queryWriter(parameters)
|
||||
];
|
||||
}
|
||||
|
||||
static _rowParserFactory(protocol) {
|
||||
const handler = rowParsers.get(protocol);
|
||||
|
||||
if (!handler) {
|
||||
// Default to no row parser
|
||||
return null;
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
static _writerFactory(protocol) {
|
||||
const handler = defaultWriters.get(protocol);
|
||||
|
||||
if (!handler) {
|
||||
throw new Error(`No writer defined for protocol ${protocol}`);
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
function getRowParser(reader) {
|
||||
return row => {
|
||||
const item = reader.read(JSON.parse(row['gremlin']));
|
||||
return { object: item['result'], bulk: item['bulk'] || 1 };
|
||||
};
|
||||
}
|
||||
|
||||
function getDefaultWriter(writer) {
|
||||
return value => writer.write(value);
|
||||
}
|
||||
|
||||
module.exports = GraphExecutor;
|
260
node_modules/cassandra-driver/lib/datastax/graph/graph-serializer.js
generated
vendored
Normal file
260
node_modules/cassandra-driver/lib/datastax/graph/graph-serializer.js
generated
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module datastax/graph/tinkerpop/graphSerializers
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @author Jorge Bay Gondra
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const typeSerializers = require('./type-serializers');
|
||||
|
||||
/**
|
||||
* GraphSON2 writer.
|
||||
*/
|
||||
class GraphSON2Writer {
|
||||
|
||||
/**
|
||||
* @param {Object} [options]
|
||||
* @param {Object} [options.serializers] An object used as an associative array with GraphSON 2 type name as keys and
|
||||
* serializer instances as values, ie: { 'g:Int64': longSerializer }.
|
||||
* @constructor
|
||||
*/
|
||||
constructor(options) {
|
||||
this._options = options || {};
|
||||
// Create instance of the default serializers
|
||||
this._serializers = this.getDefaultSerializers().map(serializerConstructor => {
|
||||
const s = new serializerConstructor();
|
||||
s.writer = this;
|
||||
return s;
|
||||
});
|
||||
|
||||
const customSerializers = this._options.serializers || {};
|
||||
|
||||
Object.keys(customSerializers).forEach(key => {
|
||||
const s = customSerializers[key];
|
||||
if (!s.serialize) {
|
||||
return;
|
||||
}
|
||||
s.writer = this;
|
||||
// Insert custom serializers first
|
||||
this._serializers.unshift(s);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default serializers to be used.
|
||||
* @returns {Array}
|
||||
*/
|
||||
getDefaultSerializers() {
|
||||
return graphSON2Serializers;
|
||||
}
|
||||
|
||||
adaptObject(value) {
|
||||
let s;
|
||||
|
||||
for (let i = 0; i < this._serializers.length; i++) {
|
||||
const currentSerializer = this._serializers[i];
|
||||
if (currentSerializer.canBeUsedFor && currentSerializer.canBeUsedFor(value)) {
|
||||
s = currentSerializer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s) {
|
||||
return s.serialize(value);
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
// We need to handle arrays when there is no serializer
|
||||
// for older versions of GraphSON
|
||||
return value.map(item => this.adaptObject(item));
|
||||
}
|
||||
|
||||
// Default (strings / objects / ...)
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GraphSON representation of the provided object instance.
|
||||
* @param {Object} obj
|
||||
* @returns {String}
|
||||
*/
|
||||
write(obj) {
|
||||
return JSON.stringify(this.adaptObject(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GraphSON3 writer.
|
||||
*/
|
||||
class GraphSON3Writer extends GraphSON2Writer {
|
||||
getDefaultSerializers() {
|
||||
return graphSON3Serializers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GraphSON2 reader.
|
||||
*/
|
||||
class GraphSON2Reader {
|
||||
/**
|
||||
* GraphSON Reader
|
||||
* @param {Object} [options]
|
||||
* @param {Object} [options.serializers] An object used as an associative array with GraphSON 2 type name as keys and
|
||||
* deserializer instances as values, ie: { 'g:Int64': longSerializer }.
|
||||
* @constructor
|
||||
*/
|
||||
constructor(options) {
|
||||
this._options = options || {};
|
||||
this._deserializers = {};
|
||||
|
||||
const defaultDeserializers = this.getDefaultDeserializers();
|
||||
Object.keys(defaultDeserializers).forEach(typeName => {
|
||||
const serializerConstructor = defaultDeserializers[typeName];
|
||||
const s = new serializerConstructor();
|
||||
s.reader = this;
|
||||
this._deserializers[typeName] = s;
|
||||
});
|
||||
|
||||
if (this._options.serializers) {
|
||||
const customSerializers = this._options.serializers || {};
|
||||
Object.keys(customSerializers).forEach(key => {
|
||||
const s = customSerializers[key];
|
||||
if (!s.deserialize) {
|
||||
return;
|
||||
}
|
||||
s.reader = this;
|
||||
this._deserializers[key] = s;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default deserializers as an associative array.
|
||||
* @returns {Object}
|
||||
*/
|
||||
getDefaultDeserializers() {
|
||||
return graphSON2Deserializers;
|
||||
}
|
||||
|
||||
read(obj) {
|
||||
if (obj === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (obj === null) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(item => this.read(item));
|
||||
}
|
||||
const type = obj[typeSerializers.typeKey];
|
||||
if (type) {
|
||||
const d = this._deserializers[type];
|
||||
if (d) {
|
||||
// Use type serializer
|
||||
return d.deserialize(obj);
|
||||
}
|
||||
return obj[typeSerializers.valueKey];
|
||||
}
|
||||
if (obj && typeof obj === 'object' && obj.constructor === Object) {
|
||||
return this._deserializeObject(obj);
|
||||
}
|
||||
// Default (for boolean, number and other scalars)
|
||||
return obj;
|
||||
}
|
||||
|
||||
_deserializeObject(obj) {
|
||||
const keys = Object.keys(obj);
|
||||
const result = {};
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
result[keys[i]] = this.read(obj[keys[i]]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GraphSON3 reader.
|
||||
*/
|
||||
class GraphSON3Reader extends GraphSON2Reader {
|
||||
getDefaultDeserializers() {
|
||||
return graphSON3Deserializers;
|
||||
}
|
||||
}
|
||||
|
||||
const graphSON2Deserializers = {
|
||||
'g:Traverser': typeSerializers.TraverserSerializer,
|
||||
'g:TraversalStrategy': typeSerializers.TraversalStrategySerializer,
|
||||
'g:Int32': typeSerializers.NumberSerializer,
|
||||
'g:Int64': typeSerializers.NumberSerializer,
|
||||
'g:Float': typeSerializers.NumberSerializer,
|
||||
'g:Double': typeSerializers.NumberSerializer,
|
||||
'g:Date': typeSerializers.DateSerializer,
|
||||
'g:Direction': typeSerializers.DirectionSerializer,
|
||||
'g:Vertex': typeSerializers.VertexSerializer,
|
||||
'g:Edge': typeSerializers.EdgeSerializer,
|
||||
'g:VertexProperty': typeSerializers.VertexPropertySerializer,
|
||||
'g:Property': typeSerializers.PropertySerializer,
|
||||
'g:Path': typeSerializers.Path3Serializer,
|
||||
'g:TextP': typeSerializers.TextPSerializer,
|
||||
'g:T': typeSerializers.TSerializer,
|
||||
'g:BulkSet': typeSerializers.BulkSetSerializer
|
||||
};
|
||||
|
||||
const graphSON3Deserializers = Object.assign({}, graphSON2Deserializers, {
|
||||
'g:List': typeSerializers.ListSerializer,
|
||||
'g:Set': typeSerializers.SetSerializer,
|
||||
'g:Map': typeSerializers.MapSerializer
|
||||
});
|
||||
|
||||
const graphSON2Serializers = [
|
||||
typeSerializers.NumberSerializer,
|
||||
typeSerializers.DateSerializer,
|
||||
typeSerializers.BytecodeSerializer,
|
||||
typeSerializers.TraverserSerializer,
|
||||
typeSerializers.TraversalStrategySerializer,
|
||||
typeSerializers.PSerializer,
|
||||
typeSerializers.TextPSerializer,
|
||||
typeSerializers.LambdaSerializer,
|
||||
typeSerializers.EnumSerializer,
|
||||
typeSerializers.VertexSerializer,
|
||||
typeSerializers.EdgeSerializer,
|
||||
typeSerializers.LongSerializer
|
||||
];
|
||||
|
||||
const graphSON3Serializers = graphSON2Serializers.concat([
|
||||
typeSerializers.ListSerializer,
|
||||
typeSerializers.SetSerializer,
|
||||
typeSerializers.MapSerializer
|
||||
]);
|
||||
|
||||
module.exports = {
|
||||
GraphSON3Writer,
|
||||
GraphSON3Reader,
|
||||
GraphSON2Writer,
|
||||
GraphSON2Reader,
|
||||
GraphSONWriter: GraphSON3Writer,
|
||||
GraphSONReader: GraphSON3Reader
|
||||
};
|
92
node_modules/cassandra-driver/lib/datastax/graph/index.d.ts
generated
vendored
Normal file
92
node_modules/cassandra-driver/lib/datastax/graph/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { types } from '../../types';
|
||||
|
||||
export namespace graph {
|
||||
interface Edge extends Element {
|
||||
outV?: Vertex;
|
||||
outVLabel?: string;
|
||||
inV?: Vertex;
|
||||
inVLabel?: string;
|
||||
properties?: object;
|
||||
}
|
||||
|
||||
interface Element {
|
||||
id: any;
|
||||
label: string;
|
||||
}
|
||||
|
||||
class GraphResultSet implements Iterator<any> {
|
||||
constructor(rs: types.ResultSet);
|
||||
|
||||
first(): any;
|
||||
|
||||
toArray(): any[];
|
||||
|
||||
values(): Iterator<any>;
|
||||
|
||||
next(value?: any): IteratorResult<any>;
|
||||
}
|
||||
|
||||
interface Path {
|
||||
labels: any[];
|
||||
objects: any[];
|
||||
}
|
||||
|
||||
interface Property {
|
||||
value: any
|
||||
key: any
|
||||
}
|
||||
|
||||
interface Vertex extends Element {
|
||||
properties?: { [key: string]: any[] }
|
||||
}
|
||||
|
||||
interface VertexProperty extends Element {
|
||||
value: any
|
||||
key: string
|
||||
properties?: any
|
||||
}
|
||||
|
||||
function asDouble(value: number): object;
|
||||
|
||||
function asFloat(value: number): object;
|
||||
|
||||
function asInt(value: number): object;
|
||||
|
||||
function asTimestamp(value: Date): object;
|
||||
|
||||
function asUdt(value: object): object;
|
||||
|
||||
interface EnumValue {
|
||||
toString(): string
|
||||
}
|
||||
|
||||
namespace t {
|
||||
const id: EnumValue;
|
||||
const key: EnumValue;
|
||||
const label: EnumValue;
|
||||
const value: EnumValue;
|
||||
}
|
||||
|
||||
namespace direction {
|
||||
// `in` is a reserved word
|
||||
const in_: EnumValue;
|
||||
const out: EnumValue;
|
||||
const both: EnumValue;
|
||||
}
|
||||
}
|
82
node_modules/cassandra-driver/lib/datastax/graph/index.js
generated
vendored
Normal file
82
node_modules/cassandra-driver/lib/datastax/graph/index.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Graph module.
|
||||
* @module datastax/graph
|
||||
*/
|
||||
|
||||
const GraphResultSet = require('./result-set');
|
||||
const getCustomTypeSerializers = require('./custom-type-serializers');
|
||||
const { asInt, asDouble, asFloat, asTimestamp, asUdt, UdtGraphWrapper, GraphTypeWrapper} = require('./wrappers');
|
||||
const { Edge, Element, Path, Property, Vertex, VertexProperty } = require('./structure');
|
||||
|
||||
class EnumValue {
|
||||
constructor(typeName, elementName) {
|
||||
this.typeName = typeName;
|
||||
this.elementName = elementName;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.elementName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a collection of tokens for more concise Traversal definitions.
|
||||
*/
|
||||
const t = {
|
||||
id: new EnumValue('T', 'id'),
|
||||
key: new EnumValue('T', 'key'),
|
||||
label: new EnumValue('T', 'label'),
|
||||
value: new EnumValue('T', 'value'),
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the edge direction.
|
||||
*/
|
||||
const direction = {
|
||||
'both': new EnumValue('Direction', 'BOTH'),
|
||||
'in': new EnumValue('Direction', 'IN'),
|
||||
'out': new EnumValue('Direction', 'OUT')
|
||||
};
|
||||
|
||||
// `in` is a reserved keyword depending on the context
|
||||
// TinkerPop JavaScript GLV only exposes `in` but it can lead to issues for TypeScript users and others.
|
||||
// Expose an extra property to represent `Direction.IN`.
|
||||
direction.in_ = direction.in;
|
||||
|
||||
module.exports = {
|
||||
Edge,
|
||||
Element,
|
||||
Path,
|
||||
Property,
|
||||
Vertex,
|
||||
VertexProperty,
|
||||
|
||||
asInt,
|
||||
asDouble,
|
||||
asFloat,
|
||||
asTimestamp,
|
||||
asUdt,
|
||||
direction,
|
||||
getCustomTypeSerializers,
|
||||
GraphResultSet,
|
||||
GraphTypeWrapper,
|
||||
t,
|
||||
UdtGraphWrapper
|
||||
};
|
334
node_modules/cassandra-driver/lib/datastax/graph/options.js
generated
vendored
Normal file
334
node_modules/cassandra-driver/lib/datastax/graph/options.js
generated
vendored
Normal file
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
const util = require('util');
|
||||
const types = require('../../types');
|
||||
const utils = require('../../utils');
|
||||
const { DefaultExecutionOptions, proxyExecuteKey } = require('../../execution-options');
|
||||
const Long = types.Long;
|
||||
|
||||
let consistencyNames;
|
||||
|
||||
const graphProtocol = Object.freeze({
|
||||
graphson1: 'graphson-1.0',
|
||||
graphson2: 'graphson-2.0',
|
||||
graphson3: 'graphson-3.0'
|
||||
});
|
||||
|
||||
const payloadKeys = Object.freeze({
|
||||
language :'graph-language',
|
||||
source: 'graph-source',
|
||||
name: 'graph-name',
|
||||
results: 'graph-results',
|
||||
writeConsistency: 'graph-write-consistency',
|
||||
readConsistency: 'graph-read-consistency',
|
||||
timeout: 'request-timeout'
|
||||
});
|
||||
|
||||
/**
|
||||
* Graph options that extends {@link QueryOptions}.
|
||||
* <p>
|
||||
* Consider using [execution profiles]{@link ExecutionProfile} if you plan to reuse options across different
|
||||
* query executions.
|
||||
* </p>
|
||||
* @typedef {QueryOptions} module:datastax/graph~GraphQueryOptions
|
||||
* @property {String} [graphLanguage] The graph language to use in graph queries.
|
||||
* @property {String} [graphResults] The protocol to use for serializing and deserializing graph results.
|
||||
* <p>
|
||||
* Note that this value should rarely be set by users and will otherwise be unset. When unset the server resolves
|
||||
* the protocol based on the <code>graphLanguage</code> specified.
|
||||
* </p>
|
||||
* @property {String} [graphName] The graph name to be used in the query. You can use <code>null</code> to clear the
|
||||
* value from the <code>DseClientOptions</code> and execute a query without a default graph.
|
||||
* @property {Number} [graphReadConsistency] Specifies the
|
||||
* [consistency level]{@link module:types~consistencies}
|
||||
* to be used for the graph read queries in this execution.
|
||||
* <p>
|
||||
* When defined, it overrides the consistency level only for the READ part of the graph query.
|
||||
* </p>
|
||||
* @property {String} [graphSource] The graph traversal source name to use in graph queries.
|
||||
* @property {Number} [graphWriteConsistency] Specifies the [consistency level]{@link module:types~consistencies} to
|
||||
* be used for the graph write queries in this execution.
|
||||
* <p>
|
||||
* When defined, it overrides the consistency level only for the WRITE part of the graph query.
|
||||
* </p>
|
||||
* @property {RetryPolicy} [retry] Sets the retry policy to be used for the graph query execution.
|
||||
* <p>
|
||||
* When not specified in the {@link GraphQueryOptions} or in the {@link ExecutionProfile}, it will use by default
|
||||
* a retry policy that does not retry graph executions.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the default options with the custom payload for a given profile.
|
||||
* @param {ProfileManager} profileManager
|
||||
* @param baseOptions
|
||||
* @param {RetryPolicy|null} defaultRetryPolicy
|
||||
* @param {ExecutionProfile} profile
|
||||
* @returns {DseClientOptions}
|
||||
* @private
|
||||
*/
|
||||
function getDefaultGraphOptions(profileManager, baseOptions, defaultRetryPolicy, profile) {
|
||||
return profileManager.getOrCreateGraphOptions(profile, function createDefaultOptions() {
|
||||
const profileOptions = profile.graphOptions || utils.emptyObject;
|
||||
const defaultProfile = profileManager.getDefault();
|
||||
const options = {
|
||||
customPayload: {
|
||||
[payloadKeys.language]: utils.allocBufferFromString(profileOptions.language || baseOptions.language),
|
||||
[payloadKeys.source]: utils.allocBufferFromString(profileOptions.source || baseOptions.source)
|
||||
},
|
||||
graphLanguage: profileOptions.language || baseOptions.language,
|
||||
graphResults: profileOptions.results || baseOptions.results,
|
||||
graphSource: profileOptions.source || baseOptions.source,
|
||||
graphName: utils.ifUndefined(profileOptions.name, baseOptions.name)
|
||||
};
|
||||
|
||||
if (profile !== defaultProfile) {
|
||||
options.retry = profile.retry || baseOptions.retry;
|
||||
} else {
|
||||
// Based on an implementation detail of the execution profiles, the retry policy for the default profile is
|
||||
// always loaded (required), but that doesn't mean that it was specified by the user.
|
||||
// If it wasn't specified by the user, use the default retry policy for graph statements.
|
||||
options.retry = defaultRetryPolicy || baseOptions.retry;
|
||||
}
|
||||
|
||||
if (baseOptions.executeAs) {
|
||||
options.customPayload[proxyExecuteKey] = utils.allocBufferFromString(baseOptions.executeAs);
|
||||
}
|
||||
|
||||
if (options.graphName) {
|
||||
options.customPayload[payloadKeys.name] = utils.allocBufferFromString(options.graphName);
|
||||
}
|
||||
|
||||
const graphResults = utils.ifUndefined(profileOptions.results, baseOptions.graphResults);
|
||||
if (graphResults !== undefined) {
|
||||
options.customPayload[payloadKeys.results] = utils.allocBufferFromString(graphResults);
|
||||
}
|
||||
|
||||
const readConsistency = utils.ifUndefined(profileOptions.readConsistency, baseOptions.readConsistency);
|
||||
if (readConsistency !== undefined) {
|
||||
options.customPayload[payloadKeys.readConsistency] =
|
||||
utils.allocBufferFromString(getConsistencyName(readConsistency));
|
||||
}
|
||||
|
||||
const writeConsistency = utils.ifUndefined(profileOptions.writeConsistency, baseOptions.writeConsistency);
|
||||
if (writeConsistency !== undefined) {
|
||||
options.customPayload[payloadKeys.writeConsistency] =
|
||||
utils.allocBufferFromString(getConsistencyName(writeConsistency));
|
||||
}
|
||||
|
||||
options.readTimeout = utils.ifUndefined3(profile.readTimeout, defaultProfile.readTimeout, baseOptions.readTimeout);
|
||||
if (options.readTimeout > 0) {
|
||||
// Write the graph read timeout payload
|
||||
options.customPayload[payloadKeys.timeout] = longBuffer(options.readTimeout);
|
||||
}
|
||||
|
||||
return options;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the payload key. If the value is not provided, it uses the value from the default profile options.
|
||||
* @param {Object} payload
|
||||
* @param {QueryOptions} profileOptions
|
||||
* @param {String} key
|
||||
* @param {String|Number|null} value
|
||||
* @param {Function} [converter]
|
||||
* @private
|
||||
*/
|
||||
function setPayloadKey(payload, profileOptions, key, value, converter) {
|
||||
converter = converter || utils.allocBufferFromString;
|
||||
if (value === null) {
|
||||
// Use null to avoid set payload for a key
|
||||
return;
|
||||
}
|
||||
|
||||
if (value !== undefined) {
|
||||
payload[key] = converter(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (profileOptions.customPayload[key]) {
|
||||
payload[key] = profileOptions.customPayload[key];
|
||||
}
|
||||
}
|
||||
|
||||
function longBuffer(value) {
|
||||
value = Long.fromNumber(value);
|
||||
return Long.toBuffer(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name in upper case of the consistency level.
|
||||
* @param {Number} consistency
|
||||
* @private
|
||||
*/
|
||||
function getConsistencyName(consistency) {
|
||||
// eslint-disable-next-line
|
||||
if (consistency == undefined) {
|
||||
//null or undefined => undefined
|
||||
return undefined;
|
||||
}
|
||||
loadConsistencyNames();
|
||||
const name = consistencyNames[consistency];
|
||||
if (!name) {
|
||||
throw new Error(util.format(
|
||||
'Consistency %s not found, use values defined as properties in types.consistencies object', consistency
|
||||
));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
function loadConsistencyNames() {
|
||||
if (consistencyNames) {
|
||||
return;
|
||||
}
|
||||
consistencyNames = {};
|
||||
const propertyNames = Object.keys(types.consistencies);
|
||||
for (let i = 0; i < propertyNames.length; i++) {
|
||||
const name = propertyNames[i];
|
||||
consistencyNames[types.consistencies[name]] = name.toUpperCase();
|
||||
}
|
||||
//Using java constants naming conventions
|
||||
consistencyNames[types.consistencies.localQuorum] = 'LOCAL_QUORUM';
|
||||
consistencyNames[types.consistencies.eachQuorum] = 'EACH_QUORUM';
|
||||
consistencyNames[types.consistencies.localSerial] = 'LOCAL_SERIAL';
|
||||
consistencyNames[types.consistencies.localOne] = 'LOCAL_ONE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a wrapper around the options related to a graph execution.
|
||||
* @internal
|
||||
* @ignore
|
||||
*/
|
||||
class GraphExecutionOptions extends DefaultExecutionOptions {
|
||||
|
||||
/**
|
||||
* Creates a new instance of GraphExecutionOptions.
|
||||
* @param {GraphQueryOptions} queryOptions The user provided query options.
|
||||
* @param {Client} client the client instance.
|
||||
* @param graphBaseOptions The default graph base options.
|
||||
* @param {RetryPolicy} defaultProfileRetryPolicy
|
||||
*/
|
||||
constructor(queryOptions, client, graphBaseOptions, defaultProfileRetryPolicy) {
|
||||
|
||||
queryOptions = queryOptions || utils.emptyObject;
|
||||
super(queryOptions, client, null);
|
||||
|
||||
this._defaultGraphOptions = getDefaultGraphOptions(
|
||||
client.profileManager, graphBaseOptions, defaultProfileRetryPolicy, this.getProfile());
|
||||
|
||||
this._preferredHost = null;
|
||||
this._graphSubProtocol = queryOptions.graphResults || this._defaultGraphOptions.graphResults;
|
||||
this._graphLanguage = queryOptions.graphLanguage || this._defaultGraphOptions.graphLanguage;
|
||||
}
|
||||
|
||||
setPreferredHost(host) {
|
||||
this._preferredHost = host;
|
||||
}
|
||||
|
||||
getPreferredHost() {
|
||||
return this._preferredHost;
|
||||
}
|
||||
|
||||
getGraphSource() {
|
||||
return this.getRawQueryOptions().graphSource || this._defaultGraphOptions.graphSource;
|
||||
}
|
||||
|
||||
getGraphLanguage() {
|
||||
return this._graphLanguage;
|
||||
}
|
||||
|
||||
setGraphLanguage(value) {
|
||||
this._graphLanguage = value;
|
||||
}
|
||||
|
||||
getGraphName() {
|
||||
return utils.ifUndefined(this.getRawQueryOptions().graphName, this._defaultGraphOptions.graphName);
|
||||
}
|
||||
|
||||
getGraphSubProtocol() {
|
||||
return this._graphSubProtocol;
|
||||
}
|
||||
|
||||
setGraphSubProtocol(protocol) {
|
||||
this._graphSubProtocol = protocol;
|
||||
}
|
||||
|
||||
/** Graph executions have a specific default read timeout */
|
||||
getReadTimeout() {
|
||||
return this.getRawQueryOptions().readTimeout || this._defaultGraphOptions.readTimeout;
|
||||
}
|
||||
|
||||
/** Graph executions have a specific default retry policy */
|
||||
getRetryPolicy() {
|
||||
return this.getRawQueryOptions().retry || this._defaultGraphOptions.retry;
|
||||
}
|
||||
|
||||
getRowParser() {
|
||||
const factory = this.getRawQueryOptions().rowParserFactory;
|
||||
|
||||
if (!factory) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return factory(this.getGraphSubProtocol());
|
||||
}
|
||||
|
||||
getQueryWriter() {
|
||||
const factory = this.getRawQueryOptions().queryWriterFactory;
|
||||
|
||||
if (!factory) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return factory(this.getGraphSubProtocol());
|
||||
}
|
||||
|
||||
setGraphPayload() {
|
||||
const options = this.getRawQueryOptions();
|
||||
const defaultOptions = this._defaultGraphOptions;
|
||||
|
||||
// Clone the existing custom payload (if any)
|
||||
const payload = Object.assign({}, this.getCustomPayload());
|
||||
|
||||
// Override the payload for DSE Graph exclusive options
|
||||
setPayloadKey(payload, defaultOptions, payloadKeys.language,
|
||||
this.getGraphLanguage() !== this._defaultGraphOptions.graphLanguage ? this.getGraphLanguage() : undefined);
|
||||
setPayloadKey(payload, defaultOptions, payloadKeys.source, options.graphSource);
|
||||
setPayloadKey(payload, defaultOptions, payloadKeys.name, options.graphName);
|
||||
setPayloadKey(payload, defaultOptions, payloadKeys.readConsistency,
|
||||
getConsistencyName(options.graphReadConsistency));
|
||||
setPayloadKey(payload, defaultOptions, payloadKeys.writeConsistency,
|
||||
getConsistencyName(options.graphWriteConsistency));
|
||||
|
||||
// Use the read timeout defined by the user or the one default to graph executions
|
||||
setPayloadKey(payload, defaultOptions, payloadKeys.timeout,
|
||||
this.getReadTimeout() > 0 ? this.getReadTimeout() : null, longBuffer);
|
||||
|
||||
// Graph result is always set
|
||||
payload[payloadKeys.results] = defaultOptions.graphResults === this.getGraphSubProtocol()
|
||||
? defaultOptions.customPayload[payloadKeys.results] : utils.allocBufferFromString(this.getGraphSubProtocol());
|
||||
|
||||
this.setCustomPayload(payload);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
GraphExecutionOptions,
|
||||
graphProtocol,
|
||||
payloadKeys
|
||||
};
|
156
node_modules/cassandra-driver/lib/datastax/graph/result-set.js
generated
vendored
Normal file
156
node_modules/cassandra-driver/lib/datastax/graph/result-set.js
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const utils = require('../../utils');
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>GraphResultSet</code>.
|
||||
* @class
|
||||
* @classdesc
|
||||
* Represents the result set of a [graph query execution]{@link Client#executeGraph} containing vertices, edges or
|
||||
* scalar values depending on the query.
|
||||
* <p>
|
||||
* It allows iteration of the items using <code>for..of</code> statements under ES2015 and exposes
|
||||
* <code>forEach()</code>, <code>first()</code> and <code>toArray()</code> to access the underlying items.
|
||||
* </p>
|
||||
* @example
|
||||
* for (let vertex of result} { ... }
|
||||
* @example
|
||||
* const arr = result.toArray();
|
||||
* @example
|
||||
* const vertex = result.first();
|
||||
* @param {ResultSet} result
|
||||
* @param {Function} [rowParser]
|
||||
* @alias module:datastax/graph~GraphResultSet
|
||||
* @constructor
|
||||
*/
|
||||
function GraphResultSet(result, rowParser) {
|
||||
/**
|
||||
* Information on the execution of a successful query:
|
||||
* @member {Object}
|
||||
* @property {Number} achievedConsistency The consistency level that has been actually achieved by the query.
|
||||
* @property {String} queriedHost The Cassandra host that coordinated this query.
|
||||
* @property {Object} triedHosts Gets the associative array of host that were queried before getting a valid response,
|
||||
* being the last host the one that replied correctly.
|
||||
* @property {Uuid} traceId Identifier of the trace session.
|
||||
* @property {Array.<string>} warnings Warning messages generated by the server when executing the query.
|
||||
*/
|
||||
this.info = result.info;
|
||||
const rows = result.rows;
|
||||
rowParser = rowParser || parsePlainJsonRow;
|
||||
|
||||
/**
|
||||
* This property has been deprecated because it may return a lower value than the actual length of the results.
|
||||
* Use <code>toArray()</code> instead.
|
||||
* <p>Gets the length of the result.</p>
|
||||
* @deprecated Use <code>toArray()</code> instead. This property will be removed in the following major version.
|
||||
* @member {Number}
|
||||
*/
|
||||
this.length = result.rowLength;
|
||||
|
||||
/**
|
||||
* A string token representing the current page state of query. It can be used in the following executions to
|
||||
* continue paging and retrieve the remained of the result for the query.
|
||||
* @member {String}
|
||||
*/
|
||||
this.pageState = result.pageState;
|
||||
|
||||
/**
|
||||
* Returns the first element of the result or null if the result is empty.
|
||||
* @returns {Object}
|
||||
*/
|
||||
this.first = function first() {
|
||||
const iterator = this.values();
|
||||
const item = iterator.next();
|
||||
if (item.done) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return item.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes a provided function once per result element.
|
||||
* @param {Function} callback Function to execute for each element, taking two arguments: currentValue and index.
|
||||
* @param {Object} [thisArg] Value to use as <code>this</code> when executing callback.
|
||||
*/
|
||||
this.forEach = function forEach(callback, thisArg) {
|
||||
if (!rows.length) {
|
||||
return;
|
||||
}
|
||||
const iterator = this.values();
|
||||
let item = iterator.next();
|
||||
let index = 0;
|
||||
while (!item.done) {
|
||||
callback.call(thisArg || this, item.value, index++);
|
||||
item = iterator.next();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Results an Array of graph result elements (vertex, edge, scalar).
|
||||
* @returns {Array}
|
||||
*/
|
||||
this.toArray = function toArray() {
|
||||
if (!rows.length) {
|
||||
return utils.emptyArray;
|
||||
}
|
||||
return utils.iteratorToArray(this.values());
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a new Iterator object that contains the values for each index in the result.
|
||||
* @returns {Iterator}
|
||||
*/
|
||||
this.values = function* values() {
|
||||
for (const traverser of this.getTraversers()) {
|
||||
const bulk = traverser.bulk || 1;
|
||||
|
||||
for (let j = 0; j < bulk; j++) {
|
||||
yield traverser.object;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the traversers represented contained in the result set.
|
||||
* @returns {Iterator}
|
||||
*/
|
||||
this.getTraversers = function* () {
|
||||
for (const row of rows) {
|
||||
yield rowParser(row);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof Symbol !== 'undefined' && typeof Symbol.iterator === 'symbol') {
|
||||
// Make iterable
|
||||
GraphResultSet.prototype[Symbol.iterator] = function getIterator() {
|
||||
return this.values();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Row} row
|
||||
* @private
|
||||
*/
|
||||
function parsePlainJsonRow(row) {
|
||||
const parsed = JSON.parse(row['gremlin']);
|
||||
return { object: parsed.result, bulk: parsed.bulk || 1 };
|
||||
}
|
||||
|
||||
module.exports = GraphResultSet;
|
167
node_modules/cassandra-driver/lib/datastax/graph/structure.js
generated
vendored
Normal file
167
node_modules/cassandra-driver/lib/datastax/graph/structure.js
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Represents a graph Element.
|
||||
* @param id
|
||||
* @param label
|
||||
* @abstract
|
||||
* @memberOf module:datastax/graph
|
||||
* @constructor
|
||||
*/
|
||||
function Element(id, label) {
|
||||
/**
|
||||
* Gets the element id.
|
||||
*/
|
||||
this.id = id;
|
||||
/**
|
||||
* Gets the element label.
|
||||
* @type {String}
|
||||
*/
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Represents a graph Vertex.
|
||||
* @param id
|
||||
* @param {String} label
|
||||
* @param {Object<string, Array>} properties
|
||||
* @extends {Element}
|
||||
* @memberOf module:datastax/graph
|
||||
* @constructor
|
||||
*/
|
||||
function Vertex(id, label, properties) {
|
||||
Element.call(this, id, label);
|
||||
/**
|
||||
* Gets the vertex properties.
|
||||
* @type {Object<string, Array>}
|
||||
*/
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
util.inherits(Vertex, Element);
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Represents a graph Edge.
|
||||
* @param id
|
||||
* @param outV
|
||||
* @param {outVLabel} outVLabel
|
||||
* @param {String} label
|
||||
* @param inV
|
||||
* @param {String} inVLabel
|
||||
* @param {Object<string, Property>} properties
|
||||
* @extends {Element}
|
||||
* @memberOf module:datastax/graph
|
||||
* @constructor
|
||||
*/
|
||||
function Edge(id, outV, outVLabel, label, inV, inVLabel, properties) {
|
||||
Element.call(this, id, label);
|
||||
/**
|
||||
* Gets the id of outgoing vertex of the edge.
|
||||
*/
|
||||
this.outV = outV;
|
||||
/**
|
||||
* Gets the label of the outgoing vertex.
|
||||
*/
|
||||
this.outVLabel = outVLabel;
|
||||
/**
|
||||
* Gets the id of the incoming vertex of the edge.
|
||||
*/
|
||||
this.inV = inV;
|
||||
|
||||
/**
|
||||
* Gets the label of the incoming vertex.
|
||||
*/
|
||||
this.inVLabel = inVLabel;
|
||||
/**
|
||||
* Gets the properties of the edge as an associative array.
|
||||
* @type {Object}
|
||||
*/
|
||||
this.properties = {};
|
||||
(function adaptProperties(self) {
|
||||
if (properties) {
|
||||
const keys = Object.keys(properties);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const k = keys[i];
|
||||
self.properties[k] = properties[k].value;
|
||||
}
|
||||
}
|
||||
})(this);
|
||||
}
|
||||
|
||||
util.inherits(Edge, Element);
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Represents a graph vertex property.
|
||||
* @param id
|
||||
* @param {String} label
|
||||
* @param value
|
||||
* @param {Object} properties
|
||||
* @extends {Element}
|
||||
* @memberOf module:datastax/graph
|
||||
* @constructor
|
||||
*/
|
||||
function VertexProperty(id, label, value, properties) {
|
||||
Element.call(this, id, label);
|
||||
this.value = value;
|
||||
this.key = this.label;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
util.inherits(VertexProperty, Element);
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Represents a property.
|
||||
* @param key
|
||||
* @param value
|
||||
* @memberOf module:datastax/graph
|
||||
* @constructor
|
||||
*/
|
||||
function Property(key, value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Represents a walk through a graph as defined by a traversal.
|
||||
* @param {Array} labels
|
||||
* @param {Array} objects
|
||||
* @memberOf module:datastax/graph
|
||||
* @constructor
|
||||
*/
|
||||
function Path(labels, objects) {
|
||||
this.labels = labels;
|
||||
this.objects = objects;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Edge,
|
||||
Element,
|
||||
Path,
|
||||
Property,
|
||||
Vertex,
|
||||
VertexProperty
|
||||
};
|
501
node_modules/cassandra-driver/lib/datastax/graph/type-serializers.js
generated
vendored
Normal file
501
node_modules/cassandra-driver/lib/datastax/graph/type-serializers.js
generated
vendored
Normal file
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module datastax/graph/tinkerpop/typeSerializers
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Jorge Bay Gondra
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// Replace dependencies to minimize code changes from Apache TinkerPop
|
||||
const t = {
|
||||
P: UnsupportedType, TextP: UnsupportedType, Traversal: UnsupportedType, Traverser: UnsupportedType,
|
||||
EnumValue: UnsupportedType
|
||||
};
|
||||
const ts = { TraversalStrategy: UnsupportedType };
|
||||
const Bytecode = UnsupportedType;
|
||||
const g = require('./index');
|
||||
const utils = { Long: UnsupportedType };
|
||||
t.t = g.t;
|
||||
t.direction = g.direction;
|
||||
|
||||
function UnsupportedType() { }
|
||||
|
||||
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'
|
||||
};
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
deserialize(obj) {
|
||||
var val = obj[valueKey];
|
||||
if (val === 'NaN') {
|
||||
return NaN;
|
||||
} else if (val === 'Infinity') {
|
||||
return Number.POSITIVE_INFINITY;
|
||||
} else if (val === '-Infinity') {
|
||||
return Number.NEGATIVE_INFINITY;
|
||||
} else {
|
||||
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 < 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) {
|
||||
return {
|
||||
[typeKey]: 'g:Lambda',
|
||||
[valueKey]: {
|
||||
'arguments': item.length,
|
||||
'language': 'gremlin-javascript',
|
||||
'script': item.toString()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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 && value.typeName && 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) {
|
||||
return {
|
||||
[typeKey]: 'g:' + item.constructor.name,
|
||||
[valueKey]: item.configuration
|
||||
};
|
||||
}
|
||||
|
||||
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 < 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 < 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
|
||||
};
|
84
node_modules/cassandra-driver/lib/datastax/graph/wrappers.js
generated
vendored
Normal file
84
node_modules/cassandra-driver/lib/datastax/graph/wrappers.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright DataStax, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const types = require('../../types');
|
||||
const { dataTypes } = types;
|
||||
|
||||
/**
|
||||
* Internal representation of a value with additional type information.
|
||||
* @internal
|
||||
* @ignore
|
||||
*/
|
||||
class GraphTypeWrapper {
|
||||
constructor(value, typeInfo) {
|
||||
this.value = value;
|
||||
this.typeInfo = typeof typeInfo === 'number' ? { code: typeInfo } : typeInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal representation of user-defined type with the metadata.
|
||||
* @internal
|
||||
* @ignore
|
||||
*/
|
||||
class UdtGraphWrapper {
|
||||
constructor(value, udtInfo) {
|
||||
this.value = value;
|
||||
|
||||
if (!udtInfo || !udtInfo.name || !udtInfo.keyspace || !udtInfo.fields) {
|
||||
throw new TypeError(`udtInfo must be an object with name, keyspace and field properties defined`);
|
||||
}
|
||||
|
||||
this.udtInfo = udtInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a number or null value to hint the client driver that the data type of the value is an int
|
||||
* @memberOf module:datastax/graph
|
||||
*/
|
||||
function asInt(value) { return new GraphTypeWrapper(value, dataTypes.int); }
|
||||
|
||||
/**
|
||||
* Wraps a number or null value to hint the client driver that the data type of the value is a double
|
||||
* @memberOf module:datastax/graph
|
||||
*/
|
||||
function asDouble(value) { return new GraphTypeWrapper(value, dataTypes.double); }
|
||||
|
||||
/**
|
||||
* Wraps a number or null value to hint the client driver that the data type of the value is a double
|
||||
* @memberOf module:datastax/graph
|
||||
*/
|
||||
function asFloat(value) { return new GraphTypeWrapper(value, dataTypes.float); }
|
||||
|
||||
/**
|
||||
* Wraps a Date or null value to hint the client driver that the data type of the value is a timestamp
|
||||
* @memberOf module:datastax/graph
|
||||
*/
|
||||
function asTimestamp(value) { return new GraphTypeWrapper(value, dataTypes.timestamp); }
|
||||
|
||||
/**
|
||||
* Wraps an Object or null value to hint the client driver that the data type of the value is a user-defined type.
|
||||
* @memberOf module:datastax/graph
|
||||
* @param {object} value The object representing the UDT.
|
||||
* @param {{name: string, keyspace: string, fields: Array}} udtInfo The UDT metadata as defined by the driver.
|
||||
*/
|
||||
function asUdt(value, udtInfo) { return new UdtGraphWrapper(value, udtInfo); }
|
||||
|
||||
module.exports = { asInt, asDouble, asFloat, asTimestamp, asUdt, UdtGraphWrapper, GraphTypeWrapper };
|
Reference in New Issue
Block a user