Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,14 @@ public void clear(String graph, boolean clearSchema) {
}

public void clear(String graph, String message) {
this.client.delete(joinPath(this.path(), graph, CLEAR),
ImmutableMap.of(CONFIRM_MESSAGE, message));
clear(null, graph, message);
}

public void clear(String graphSpace, String graph, String message) {
String path = (graphSpace == null)
? joinPath(this.path(), graph, CLEAR)
: joinPath(this.path(), graphSpace, graph, CLEAR);
this.client.delete(path, ImmutableMap.of(CONFIRM_MESSAGE, message));
}

public Map<String, String> update(String name, String nickname) {
Expand Down Expand Up @@ -198,51 +204,85 @@ public Map<String, String> reload() {
}

public void mode(String graph, GraphMode mode) {
// NOTE: Must provide id for PUT. If you use "graph/mode", "/" will
// be encoded to "%2F". So use "mode" here, although inaccurate.
this.client.put(joinPath(this.path(), graph, MODE), null, mode);
mode(null, graph, mode);
}

public GraphMode mode(String graph) {
RestResult result = this.client.get(joinPath(this.path(), graph), MODE);
@SuppressWarnings("unchecked")
Map<String, String> mode = result.readObject(Map.class);
String value = mode.get(MODE);
if (value == null) {
throw new InvalidResponseException("Invalid response, expect 'mode' in response");
}
try {
return GraphMode.valueOf(value);
} catch (IllegalArgumentException e) {
throw new InvalidResponseException("Invalid GraphMode value '%s'", value);
public void mode(String graphSpace, String graph, GraphMode mode) {
// NOTE: Must provide id for PUT. If you use "graph/mode", "/" will
// be encoded to "%2F". So use "mode" here, although inaccurate.
if (graphSpace == null) {
this.client.put(joinPath(this.path(), graph, MODE), null, mode);
return;
}
this.client.put(joinPath(this.path(), graphSpace, graph, MODE), null, mode);
}

public void readMode(String graph, GraphReadMode readMode) {
readMode(null, graph, readMode);
}


public void readMode(String graphSpace, String graph, GraphReadMode readMode) {
this.client.checkApiVersion("0.59", "graph read mode");
// NOTE: Must provide id for PUT. If you use "graph/graph_read_mode", "/"
// will be encoded to "%2F". So use "graph_read_mode" here, although
// inaccurate.
this.client.put(joinPath(this.path(), graph, GRAPH_READ_MODE), null, readMode);
if (graphSpace == null) {
this.client.put(joinPath(this.path(), graph, GRAPH_READ_MODE), null, readMode);
return;
}
this.client.put(joinPath(this.path(), graphSpace, graph, GRAPH_READ_MODE), null, readMode);
}

public GraphReadMode readMode(String graph) {
this.client.checkApiVersion("0.59", "graph read mode");
RestResult result = this.client.get(joinPath(this.path(), graph), GRAPH_READ_MODE);
/**
* Get graph mode value from server response
*
* @param graphSpace the graph space name, null for non-graphspace mode
* @param graph the graph name
* @param modeKey the mode key in response (MODE or GRAPH_READ_MODE)
* @param enumClass the enum class type
* @return the mode enum value
*/
private <T extends Enum<T>> T getModeValue(String graphSpace, String graph,
String modeKey, Class<T> enumClass) {
String path = (graphSpace != null)
? joinPath(this.path(), graphSpace, graph)
: joinPath(this.path(), graph);

RestResult result = this.client.get(path, modeKey);
@SuppressWarnings("unchecked")
Map<String, String> readMode = result.readObject(Map.class);
String value = readMode.get(GRAPH_READ_MODE);
Map<String, String> map = result.readObject(Map.class);
String value = map.get(modeKey);

if (value == null) {
throw new InvalidResponseException("Invalid response, expect 'graph_read_mode' " +
"in response");
throw new InvalidResponseException(
"Invalid response, expect '%s' in response", modeKey);
}
try {
return GraphReadMode.valueOf(value);
return Enum.valueOf(enumClass, value);
} catch (IllegalArgumentException e) {
throw new InvalidResponseException("Invalid GraphReadMode value '%s'", value);
throw new InvalidResponseException(
"Invalid %s value '%s'", enumClass.getSimpleName(), value);
}
}

public GraphMode mode(String graphSpace, String graph) {
return getModeValue(graphSpace, graph, MODE, GraphMode.class);
}

public GraphMode mode(String graph) {
return mode(null, graph);
}

public GraphReadMode readMode(String graphSpace, String graph) {
this.client.checkApiVersion("0.59", "graph read mode");
return getModeValue(graphSpace, graph, GRAPH_READ_MODE, GraphReadMode.class);
}

public GraphReadMode readMode(String graph) {
return readMode(null, graph);
}

public String clone(String graph, Map<String, Object> body) {
RestResult result = this.client.post(joinPath(this.path(), graph,
"clone"), body);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.util.Map;

import org.apache.hugegraph.driver.VersionManager;
import org.apache.hugegraph.exception.ServerException;
import org.apache.hugegraph.rest.AbstractRestClient;
import org.apache.hugegraph.rest.ClientException;
Expand All @@ -39,18 +40,18 @@
public class RestClient extends AbstractRestClient {

private static final int SECOND = 1000;
private String version;
@Getter
@Setter
private boolean supportGs;
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The default value for supportGs has changed from explicit false initialization to implicit false (Java's default for boolean fields). While functionally equivalent, the previous explicit initialization made the intent clearer. Consider restoring the explicit initialization: private boolean supportGs = false;

Suggested change
private boolean supportGs;
private boolean supportGs = false;

Copilot uses AI. Check for mistakes.
private Version apiVersion = null;

static {
SimpleModule module = new SimpleModule();
module.addDeserializer(Path.class, new PathDeserializer());
RestResult.registerModule(module);
}

private Version apiVersion = null;
@Setter
@Getter
private boolean supportGs = false;

public RestClient(String url, String username, String password, int timeout) {
super(url, username, password, timeout * SECOND);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ public void clearGraph(String graph, String message) {
this.graphsAPI.clear(graph, message);
}

public void clearGraph(String graphSpace, String graph, String message) {
this.graphsAPI.clear(graphSpace, graph, message);
}

public void update(String graph, String nickname) {
this.graphsAPI.update(graph, nickname);
}
Expand All @@ -115,14 +119,30 @@ public void mode(String graph, GraphMode mode) {
this.graphsAPI.mode(graph, mode);
}

public void mode(String graphSpace, String graph, GraphMode mode) {
this.graphsAPI.mode(graphSpace, graph, mode);
}

public GraphMode mode(String graph) {
return this.graphsAPI.mode(graph);
}

public GraphMode mode(String graphSpace, String graph) {
return this.graphsAPI.mode(graphSpace, graph);
}

public void readMode(String graphSpace, String graph, GraphReadMode readMode) {
this.graphsAPI.readMode(graphSpace, graph, readMode);
}

public void readMode(String graph, GraphReadMode readMode) {
this.graphsAPI.readMode(graph, readMode);
}

public GraphReadMode readMode(String graphSpace, String graph) {
return this.graphsAPI.readMode(graphSpace, graph);
}

public GraphReadMode readMode(String graph) {
return this.graphsAPI.readMode(graph);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import java.io.Closeable;

import lombok.Getter;

import org.apache.hugegraph.client.RestClient;
import org.apache.hugegraph.rest.ClientException;
import org.apache.hugegraph.rest.RestClientConfig;
Expand All @@ -42,8 +44,11 @@ public class HugeClient implements Closeable {
ClientVersion.check();
}

@Getter
protected String graphSpaceName;
@Getter
protected String graphName;

private final boolean borrowedClient;
private final RestClient client;
private VersionManager version;
Expand Down Expand Up @@ -173,18 +178,10 @@ private void checkServerApiVersion() {
// 0.81 equals to the {latest_api_version} +10
VersionUtil.check(apiVersion, "0.38", "0.81", "hugegraph-api in server");
this.client.apiVersion(apiVersion);
boolean supportGs = VersionUtil.gte(this.version.getCoreVersion(), "2.0");
boolean supportGs = VersionUtil.gte(this.version.getCoreVersion(), "1.7.0");
this.client.setSupportGs(supportGs);
}

public String getGraphSpaceName() {
return graphSpaceName;
}

public String getGraphName() {
return graphName;
}

public GraphsManager graphs() {
return this.graphs;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,45 @@

package org.apache.hugegraph.structure.constant;

/**
* GraphMode defines the operational modes of a HugeGraph instance.
* Different modes have different permissions for schema and vertex ID creation.
*/
public enum GraphMode {

/*
* None mode is regular mode
* 1. Not allowed to create schema with specified id
* 2. Not support create vertex with id for AUTOMATIC id strategy
/**
* NONE mode is the default regular mode for normal graph operations.
* Restrictions:
* 1. Not allowed to create schema with specified ID
* 2. Not allowed to create vertex with custom ID for AUTOMATIC ID strategy
* Use case: Daily graph database operations
*/
NONE(1, "none"),

/*
* Restoring mode is used to restore schema and graph data to an new graph.
* 1. Support create schema with specified id
* 2. Support create vertex with id for AUTOMATIC id strategy
/**
* RESTORING mode is used to restore schema and graph data to a new graph.
* This mode allows full control over IDs during restoration.
* Permissions:
* 1. Allowed to create schema with specified ID
* 2. Allowed to create vertex with custom ID for AUTOMATIC ID strategy
* Use case: Database backup recovery, graph migration
*/
RESTORING(2, "restoring"),

/*
* MERGING mode is used to merge schema and graph data to an existing graph.
* 1. Not allowed to create schema with specified id
* 2. Support create vertex with id for AUTOMATIC id strategy
/**
* MERGING mode is used to merge schema and graph data into an existing graph.
* This mode allows vertex ID control but not schema ID control to avoid conflicts.
* Permissions:
* 1. Not allowed to create schema with specified ID (to prevent conflicts)
* 2. Allowed to create vertex with custom ID for AUTOMATIC ID strategy
* Use case: Data merging, incremental data import
*/
MERGING(3, "merging"),

/*
* LOADING mode used to load data via hugegraph-loader.
/**
* LOADING mode is used for bulk data loading via hugegraph-loader.
* This mode is optimized for high-throughput data ingestion.
* Use case: Bulk data import operations
*/
LOADING(4, "loading");

Expand All @@ -62,10 +76,22 @@ public String string() {
return this.name;
}

/**
* Check if the graph is in maintenance mode (RESTORING or MERGING).
* In maintenance mode, the graph allows creating vertices with custom IDs.
*
* @return true if mode is RESTORING or MERGING
*/
public boolean maintaining() {
return this == RESTORING || this == MERGING;
}

/**
* Check if the graph is in loading mode.
* Loading mode is optimized for bulk data import operations.
*
* @return true if mode is LOADING
*/
public boolean loading() {
return this == LOADING;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,30 @@

package org.apache.hugegraph.structure.constant;

/**
* GraphReadMode defines the read modes for querying graph data.
* This determines which type of data (OLTP/OLAP) should be included in query results.
*/
public enum GraphReadMode {

/**
* ALL mode returns both OLTP and OLAP data.
* Use case: When you need complete data from both transactional and analytical storage
*/
ALL(1, "all"),

/**
* OLTP_ONLY mode returns only Online Transaction Processing data.
* OLTP data is optimized for real-time queries and low-latency transactions.
* Use case: Real-time queries, transactional operations
*/
OLTP_ONLY(2, "oltp_only"),

/**
* OLAP_ONLY mode returns only Online Analytical Processing data.
* OLAP data is optimized for complex analytical queries and large-scale computations.
* Use case: Big data analytics, graph algorithms, complex queries
*/
OLAP_ONLY(3, "olap_only");

private final byte code;
Expand All @@ -42,6 +60,11 @@ public String string() {
return this.name;
}

/**
* Check if this mode includes OLAP data in query results.
*
* @return true if mode is ALL or OLAP_ONLY
*/
public boolean showOlap() {
return this == ALL || this == OLAP_ONLY;
}
Expand Down
Loading