
org.apache.tinkerpop.gremlin.orientdb.OrientGraph Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of orientdb-gremlin Show documentation
Show all versions of orientdb-gremlin Show documentation
TinkerPop3 Graph Structure Implementation for OrientDB
package org.apache.tinkerpop.gremlin.orientdb;
import com.orientechnologies.common.exception.OException;
import com.orientechnologies.common.io.OIOException;
import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.common.util.OCallable;
import com.orientechnologies.orient.core.command.OCommandRequest;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.OPartitionedDatabasePool;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.exception.ODatabaseException;
import com.orientechnologies.orient.core.exception.OSecurityAccessException;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.index.OIndexManager;
import com.orientechnologies.orient.core.index.OPropertyIndexDefinition;
import com.orientechnologies.orient.core.iterator.ORecordIteratorClass;
import com.orientechnologies.orient.core.metadata.schema.*;
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.record.impl.ODocumentInternal;
import com.orientechnologies.orient.core.sql.OCommandSQL;
import com.orientechnologies.orient.core.storage.OStorage;
import com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.NotImplementedException;
import org.apache.tinkerpop.gremlin.orientdb.traversal.strategy.optimization.OrientGraphStepStrategy;
import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.structure.*;
import org.apache.tinkerpop.gremlin.structure.io.Io;
import org.apache.tinkerpop.gremlin.structure.io.Io.Builder;
import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static org.apache.tinkerpop.gremlin.orientdb.StreamUtils.asStream;
@Graph.OptIn(Graph.OptIn.SUITE_STRUCTURE_STANDARD)
@Graph.OptIn(Graph.OptIn.SUITE_STRUCTURE_INTEGRATE)
@Graph.OptIn(Graph.OptIn.SUITE_STRUCTURE_PERFORMANCE)
@Graph.OptIn(Graph.OptIn.SUITE_PROCESS_STANDARD)
@Graph.OptIn(Graph.OptIn.SUITE_PROCESS_COMPUTER)
@Graph.OptIn(Graph.OptIn.SUITE_PROCESS_PERFORMANCE)
@Graph.OptIn(Graph.OptIn.SUITE_GROOVY_PROCESS_STANDARD)
@Graph.OptIn(Graph.OptIn.SUITE_GROOVY_PROCESS_COMPUTER)
@Graph.OptIn(Graph.OptIn.SUITE_GROOVY_ENVIRONMENT)
@Graph.OptIn(Graph.OptIn.SUITE_GROOVY_ENVIRONMENT_INTEGRATE)
@Graph.OptIn(Graph.OptIn.SUITE_GROOVY_ENVIRONMENT_PERFORMANCE)
public final class OrientGraph implements Graph {
static {
TraversalStrategies.GlobalCache.registerStrategies(
OrientGraph.class,
TraversalStrategies.GlobalCache.getStrategies(Graph.class).clone()
.addStrategies(OrientGraphStepStrategy.instance()));
}
private static final Map INTERNAL_CLASSES_TO_TINKERPOP_CLASSES;
static {
INTERNAL_CLASSES_TO_TINKERPOP_CLASSES = new HashMap<>();
INTERNAL_CLASSES_TO_TINKERPOP_CLASSES.put(OImmutableClass.VERTEX_CLASS_NAME, Vertex.DEFAULT_LABEL);
INTERNAL_CLASSES_TO_TINKERPOP_CLASSES.put(OImmutableClass.EDGE_CLASS_NAME, Edge.DEFAULT_LABEL);
}
public static String CONFIG_URL = "orient-url";
public static String CONFIG_USER = "orient-user";
public static String CONFIG_PASS = "orient-pass";
public static String CONFIG_CREATE = "orient-create";
public static String CONFIG_OPEN = "orient-open";
public static String CONFIG_TRANSACTIONAL = "orient-transactional";
public static String CONFIG_POOL_SIZE = "orient-max-poolsize";
public static String CONFIG_LABEL_AS_CLASSNAME = "orient-label-as-classname";
protected boolean connectionFailed;
protected ODatabaseDocumentTx database;
protected final Features features;
protected final Configuration configuration;
protected final OPartitionedReCreatableDatabasePool pool;
protected final String user;
protected final String password;
public static OrientGraph open(final Configuration config) {
OrientGraphFactory factory = new OrientGraphFactory(config);
if (config.containsKey(CONFIG_POOL_SIZE))
factory.setupPool(config.getInt(CONFIG_POOL_SIZE));
return factory.getNoTx();
}
public OrientGraph(final ODatabaseDocumentTx database, final Configuration configuration, final String user, final String password) {
this.pool = null;
this.user = user;
this.password = password;
this.database = database;
this.configuration = configuration;
this.connectionFailed = false;
if (configuration.getBoolean(CONFIG_TRANSACTIONAL, false)) {
this.features = ODBFeatures.OrientFeatures.INSTANCE_TX;
} else {
this.features = ODBFeatures.OrientFeatures.INSTANCE_NOTX;
}
}
public OrientGraph(final OPartitionedReCreatableDatabasePool pool, final Configuration configuration) {
this.pool = pool;
this.database = pool.acquire();
this.user = "";
this.password = "";
this.connectionFailed = false;
makeActive();
this.configuration = configuration;
if (configuration.getBoolean(CONFIG_TRANSACTIONAL, false)) {
this.features = ODBFeatures.OrientFeatures.INSTANCE_TX;
} else {
this.features = ODBFeatures.OrientFeatures.INSTANCE_NOTX;
}
}
public Features features() {
return features;
}
public ODatabaseDocumentTx database() {
return database;
}
private void makeActiveDb() {
final ODatabaseDocument tlDb = ODatabaseRecordThreadLocal.INSTANCE.getIfDefined();
if (database != null && tlDb != database) {
database.activateOnCurrentThread();
ODatabaseRecordThreadLocal.INSTANCE.set(database);
}
}
public void makeActive() {
makeActiveDb();
if (this.connectionFailed) {
this.connectionFailed = false;
try {
if (this.pool != null) {
this.pool.reCreatePool();
this.database = this.pool.acquire();
} else {
ODatabaseDocumentTx replaceDb = new ODatabaseDocumentTx(this.database.getURL(), this.database.isKeepStorageOpen());
replaceDb.open(user, password);
this.database = replaceDb;
}
makeActiveDb();
} catch (OException e) {
OLogManager.instance().info(this, "Recreation of connection resulted in exception", e);
}
}
}
private T executeWithConnectionCheck(Supplier toExecute) {
try {
T result = toExecute.get();
this.connectionFailed = false;
return result;
} catch (OException e) {
this.connectionFailed = true;
OLogManager.instance().info(this, "Error during db request", e);
throw e;
}
}
@Override
public Vertex addVertex(Object... keyValues) {
return executeWithConnectionCheck(() -> {
makeActive();
ElementHelper.legalPropertyKeyValueArray(keyValues);
if (ElementHelper.getIdValue(keyValues).isPresent()) throw Vertex.Exceptions.userSuppliedIdsNotSupported();
String label = ElementHelper.getLabelValue(keyValues).orElse(OImmutableClass.VERTEX_CLASS_NAME);
String className = labelToClassName(label, OImmutableClass.VERTEX_CLASS_NAME);
OrientVertex vertex = new OrientVertex(this, className);
vertex.property(keyValues);
vertex.save();
return vertex;
});
}
public Object executeSql(String sql) {
return executeWithConnectionCheck(() -> {
makeActive();
OCommandRequest command = database.command(new OCommandSQL(sql));
return command.execute();
});
}
public Object executeCommand(OCommandRequest command) {
return executeWithConnectionCheck(() -> {
return command.execute();
});
}
@Override
public C compute(Class graphComputerClass) throws IllegalArgumentException {
throw new NotImplementedException();
}
@Override
public GraphComputer compute() throws IllegalArgumentException {
throw new NotImplementedException();
}
@Override
public Iterator vertices(Object... vertexIds) {
return executeWithConnectionCheck(() -> {
makeActive();
return elements(
OImmutableClass.VERTEX_CLASS_NAME,
r -> new OrientVertex(this, getRawDocument(r)),
vertexIds);
});
}
/**
* Convert a label to orientdb class name
*/
public String labelToClassName(String label, String prefix) {
if (configuration.getBoolean(CONFIG_LABEL_AS_CLASSNAME, false)) {
return label;
}
return label.equals(prefix) ? prefix : prefix + "_" + label;
}
/**
* Convert a orientdb class name to label
*/
public String classNameToLabel(String className) {
if (INTERNAL_CLASSES_TO_TINKERPOP_CLASSES.containsKey(className)) {
return INTERNAL_CLASSES_TO_TINKERPOP_CLASSES.get(className);
}
if (configuration.getBoolean(CONFIG_LABEL_AS_CLASSNAME, false)) {
return className;
}
return className.substring(2);
}
protected Object convertValue(final OIndex> idx, Object iValue) {
if (iValue != null) {
final OType[] types = idx.getKeyTypes();
if (types.length == 0)
iValue = iValue.toString();
else
iValue = OType.convert(iValue, types[0].getDefaultJavaType());
}
return iValue;
}
public Stream getIndexedVertices(OIndex
© 2015 - 2025 Weber Informatics LLC | Privacy Policy