Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wokdlhX3] Extract code from APOC core which is only used in APOC extended #3361

Merged
merged 11 commits into from
Jan 16, 2023
30 changes: 30 additions & 0 deletions extended/src/main/antlr/apoc/custom/Signature.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
grammar Signature;

procedure: namespace? name '(' (parameter',')*(parameter)? ')' '::' results ;
function: namespace? name '(' (parameter',')*(parameter)? ')' '::' (type | '(' type ')');
results: empty | '(' (result',')*(result) ')' ;
parameter: name ('=' defaultValue)? '::' type ;
result: name '::' type ;
namespace: (name'.')+ ;
name: IDENTIFIER | QUOTED_IDENTIFIER ;
empty: 'VOID' ;
type: opt_type | list_type ;
defaultValue: value;

list_type: 'LIST''?'?' OF '+opt_type ;
opt_type: base_type'?'? ;
base_type: 'MAP' | 'ANY' | 'NODE' | 'REL' | 'RELATIONSHIP' | 'EDGE' | 'PATH' | 'NUMBER' | 'LONG' | 'INT' | 'INTEGER' | 'FLOAT' | 'DOUBLE' | 'BOOL' | 'BOOLEAN' | 'DATE' | 'TIME' | 'LOCALTIME' | 'DATETIME' | 'LOCALDATETIME' | 'DURATION' | 'POINT' | 'GEO' | 'GEOMETRY' | 'STRING' | 'TEXT' ;
NEWLINE: [\r\n]+ ;
QUOTED_IDENTIFIER: '`' [^`]+? '`' ;
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]+ ;
WS: [ \t\r\n]+ -> skip ;
value: nullValue | INT_VALUE | FLOAT_VALUE | boolValue | mapValue | listValue | stringValue;
INT_VALUE: [0-9]+;
FLOAT_VALUE: ([0-9]+'.'[0-9]+) | 'NaN';
boolValue: 'true'|'false';
stringValue: QUOTED_STRING_VALUE | PLAIN_STRING_VALUE;
QUOTED_STRING_VALUE: '"'[^"]+?'"';
PLAIN_STRING_VALUE: .+?;
nullValue: 'null';
listValue: '[' ((value',')*value)?']';
mapValue: '{' (((name ':' value)',')*(name ':' value) | ((name '=' value)',')*(name '=' value))? '}';
16 changes: 16 additions & 0 deletions extended/src/main/java/apoc/Description.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package apoc;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author mh
* @since 11.04.16
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Description {
String value();
}
8 changes: 8 additions & 0 deletions extended/src/main/java/apoc/ExtendedApocConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@ public Iterator<String> getKeys(String prefix) {
return config.getKeys(prefix);
}

public boolean containsKey(String key) {
return config.containsKey(key);
}

public boolean getBoolean(String key, boolean defaultValue) {
return getConfig().getBoolean(key, defaultValue);
}

public <T extends Enum<T>> T getEnumProperty(String key, Class<T> cls, T defaultValue) {
var value = config.getString(key, defaultValue.toString()).trim();
try {
Expand Down
13 changes: 13 additions & 0 deletions extended/src/main/java/apoc/ExtendedSystemLabels.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package apoc;

import org.neo4j.graphdb.Label;

public enum ExtendedSystemLabels implements Label
{
ApocCypherProcedures,
ApocCypherProceduresMeta,
Procedure,
Function,
ApocUuid,
DataVirtualizationCatalog
}
26 changes: 26 additions & 0 deletions extended/src/main/java/apoc/ExtendedSystemPropertyKeys.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package apoc;

public enum ExtendedSystemPropertyKeys
{
// cypher stored procedures/functions
inputs,
description,
mode,
outputs,
output,
forceSingle,
prefix,

// triggers
selector,
params,
paused,

// dv
data,

// uuid handler
label,
addToSetLabel,
propertyName
}
4 changes: 2 additions & 2 deletions extended/src/main/java/apoc/TTLConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public Values configFor(GraphDatabaseAPI db) {
String apocTTLEnabledDb = String.format(ExtendedApocConfig.APOC_TTL_ENABLED_DB, db.databaseName());
String apocTTLScheduleDb = String.format(ExtendedApocConfig.APOC_TTL_SCHEDULE_DB, db.databaseName());
String apocTTLLimitDb = String.format(ExtendedApocConfig.APOC_TTL_LIMIT_DB, db.databaseName());
boolean enabled = apocConfig.getBoolean(ExtendedApocConfig.APOC_TTL_ENABLED, false);
boolean dbEnabled = apocConfig.getBoolean(apocTTLEnabledDb, enabled);
boolean enabled = apocConfig.getConfig().getBoolean(ExtendedApocConfig.APOC_TTL_ENABLED, false);
boolean dbEnabled = apocConfig.getConfig().getBoolean(apocTTLEnabledDb, enabled);

if (dbEnabled) {
long ttlSchedule = apocConfig.getInt(ExtendedApocConfig.APOC_TTL_SCHEDULE, DEFAULT_SCHEDULE);
Expand Down
14 changes: 3 additions & 11 deletions extended/src/main/java/apoc/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import apoc.ApocConfig;
import apoc.Extended;
import apoc.result.MapResult;
import apoc.util.Util;
import apoc.util.collection.Iterators;
import org.apache.commons.configuration2.Configuration;
import org.neo4j.common.DependencyResolver;
import org.neo4j.internal.kernel.api.procs.ProcedureCallContext;
import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.procedure.Admin;
import org.neo4j.procedure.Context;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Procedure;
Expand All @@ -34,27 +32,21 @@ public ConfigResult(String key, Object value) {
}
}

@Context
public SecurityContext securityContext;

@Context
public ProcedureCallContext callContext;

@Context
public DependencyResolver dependencyResolver;

@Admin
@Description("apoc.config.list | Lists the Neo4j configuration as key,value table")
@Procedure
public Stream<ConfigResult> list() {
Util.checkAdmin(securityContext, callContext,"apoc.config.list");
Configuration config = dependencyResolver.resolveDependency(ApocConfig.class).getConfig();
return Iterators.stream(config.getKeys()).map(s -> new ConfigResult(s, config.getString(s)));
}

@Admin
@Description("apoc.config.map | Lists the Neo4j configuration as map")
@Procedure
public Stream<MapResult> map() {
Util.checkAdmin(securityContext,callContext, "apoc.config.map");
Configuration config = dependencyResolver.resolveDependency(ApocConfig.class).getConfig();
Map<String, Object> configMap = Iterators.stream(config.getKeys())
.collect(Collectors.toMap(s -> s, s -> config.getString(s)));
Expand Down
71 changes: 36 additions & 35 deletions extended/src/main/java/apoc/custom/CypherProceduresHandler.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package apoc.custom;

import apoc.ApocConfig;
import apoc.SystemLabels;
import apoc.ExtendedSystemLabels;
import apoc.ExtendedSystemPropertyKeys;
import apoc.SystemPropertyKeys;
import apoc.util.JsonUtil;
import apoc.util.Util;
Expand Down Expand Up @@ -140,10 +141,10 @@ public Mode mode(String s) {
public Stream<ProcedureOrFunctionDescriptor> readSignatures() {
List<ProcedureOrFunctionDescriptor> descriptors;
try (Transaction tx = systemDb.beginTx()) {
descriptors = tx.findNodes(SystemLabels.ApocCypherProcedures, SystemPropertyKeys.database.name(), api.databaseName()).stream().map(node -> {
if (node.hasLabel(SystemLabels.Procedure)) {
descriptors = tx.findNodes( ExtendedSystemLabels.ApocCypherProcedures, SystemPropertyKeys.database.name(), api.databaseName()).stream().map(node -> {
if (node.hasLabel(ExtendedSystemLabels.Procedure)) {
return procedureDescriptor(node);
} else if (node.hasLabel(SystemLabels.Function)) {
} else if (node.hasLabel(ExtendedSystemLabels.Function)) {
return userFunctionDescriptor(node);
} else {
throw new IllegalStateException("don't know what to do with systemdb node " + node);
Expand All @@ -158,18 +159,18 @@ private ProcedureDescriptor procedureDescriptor(Node node) {
String statement = (String) node.getProperty(SystemPropertyKeys.statement.name());

String name = (String) node.getProperty(SystemPropertyKeys.name.name());
String description = (String) node.getProperty(SystemPropertyKeys.description.name(), null);
String[] prefix = (String[]) node.getProperty(SystemPropertyKeys.prefix.name(), new String[]{PREFIX});
String description = (String) node.getProperty( ExtendedSystemPropertyKeys.description.name(), null);
String[] prefix = (String[]) node.getProperty(ExtendedSystemPropertyKeys.prefix.name(), new String[]{PREFIX});

String property = (String) node.getProperty(SystemPropertyKeys.inputs.name());
String property = (String) node.getProperty(ExtendedSystemPropertyKeys.inputs.name());
List<FieldSignature> inputs = deserializeSignatures(property);

List<FieldSignature> outputSignature = deserializeSignatures((String) node.getProperty(SystemPropertyKeys.outputs.name()));
List<FieldSignature> outputSignature = deserializeSignatures((String) node.getProperty(ExtendedSystemPropertyKeys.outputs.name()));
return new ProcedureDescriptor(Signatures.createProcedureSignature(
new QualifiedName(prefix, name),
inputs,
outputSignature,
Mode.valueOf((String) node.getProperty(SystemPropertyKeys.mode.name())),
Mode.valueOf((String) node.getProperty(ExtendedSystemPropertyKeys.mode.name())),
false,
null,
new String[0],
Expand All @@ -186,17 +187,17 @@ private UserFunctionDescriptor userFunctionDescriptor(Node node) {
String statement = (String) node.getProperty(SystemPropertyKeys.statement.name());

String name = (String) node.getProperty(SystemPropertyKeys.name.name());
String description = (String) node.getProperty(SystemPropertyKeys.description.name(), null);
String[] prefix = (String[]) node.getProperty(SystemPropertyKeys.prefix.name(), new String[]{PREFIX});
String description = (String) node.getProperty(ExtendedSystemPropertyKeys.description.name(), null);
String[] prefix = (String[]) node.getProperty(ExtendedSystemPropertyKeys.prefix.name(), new String[]{PREFIX});

String property = (String) node.getProperty(SystemPropertyKeys.inputs.name());
String property = (String) node.getProperty(ExtendedSystemPropertyKeys.inputs.name());
List<FieldSignature> inputs = deserializeSignatures(property);

boolean forceSingle = (boolean) node.getProperty(SystemPropertyKeys.forceSingle.name(), false);
boolean forceSingle = (boolean) node.getProperty(ExtendedSystemPropertyKeys.forceSingle.name(), false);
return new UserFunctionDescriptor(new UserFunctionSignature(
new QualifiedName(prefix, name),
inputs,
typeof((String) node.getProperty(SystemPropertyKeys.output.name())),
typeof((String) node.getProperty(ExtendedSystemPropertyKeys.output.name())),
null,
description,
"apoc.custom",
Expand Down Expand Up @@ -240,16 +241,16 @@ private <T> T withSystemDb(Function<Transaction, T> action) {

public void storeFunction(UserFunctionSignature signature, String statement, boolean forceSingle) {
withSystemDb(tx -> {
Node node = Util.mergeNode(tx, SystemLabels.ApocCypherProcedures, SystemLabels.Function,
Node node = Util.mergeNode(tx, ExtendedSystemLabels.ApocCypherProcedures, ExtendedSystemLabels.Function,
Pair.of(SystemPropertyKeys.database.name(), api.databaseName()),
Pair.of(SystemPropertyKeys.name.name(), signature.name().name()),
Pair.of(SystemPropertyKeys.prefix.name(), signature.name().namespace())
Pair.of(ExtendedSystemPropertyKeys.prefix.name(), signature.name().namespace())
);
node.setProperty(SystemPropertyKeys.description.name(), signature.description().orElse(null));
node.setProperty(ExtendedSystemPropertyKeys.description.name(), signature.description().orElse(null));
node.setProperty(SystemPropertyKeys.statement.name(), statement);
node.setProperty(SystemPropertyKeys.inputs.name(), serializeSignatures(signature.inputSignature()));
node.setProperty(SystemPropertyKeys.output.name(), signature.outputType().toString());
node.setProperty(SystemPropertyKeys.forceSingle.name(), forceSingle);
node.setProperty(ExtendedSystemPropertyKeys.inputs.name(), serializeSignatures(signature.inputSignature()));
node.setProperty(ExtendedSystemPropertyKeys.output.name(), signature.outputType().toString());
node.setProperty(ExtendedSystemPropertyKeys.forceSingle.name(), forceSingle);

setLastUpdate(tx);
registerFunction(signature, statement, forceSingle);
Expand All @@ -259,16 +260,16 @@ public void storeFunction(UserFunctionSignature signature, String statement, boo

public void storeProcedure(ProcedureSignature signature, String statement) {
withSystemDb(tx -> {
Node node = Util.mergeNode(tx, SystemLabels.ApocCypherProcedures, SystemLabels.Procedure,
Node node = Util.mergeNode(tx, ExtendedSystemLabels.ApocCypherProcedures, ExtendedSystemLabels.Procedure,
Pair.of(SystemPropertyKeys.database.name(), api.databaseName()),
Pair.of(SystemPropertyKeys.name.name(), signature.name().name()),
Pair.of(SystemPropertyKeys.prefix.name(), signature.name().namespace())
Pair.of(ExtendedSystemPropertyKeys.prefix.name(), signature.name().namespace())
);
node.setProperty(SystemPropertyKeys.description.name(), signature.description().orElse(null));
node.setProperty(ExtendedSystemPropertyKeys.description.name(), signature.description().orElse(null));
node.setProperty(SystemPropertyKeys.statement.name(), statement);
node.setProperty(SystemPropertyKeys.inputs.name(), serializeSignatures(signature.inputSignature()));
node.setProperty(SystemPropertyKeys.outputs.name(), serializeSignatures(signature.outputSignature()));
node.setProperty(SystemPropertyKeys.mode.name(), signature.mode().name());
node.setProperty(ExtendedSystemPropertyKeys.inputs.name(), serializeSignatures(signature.inputSignature()));
node.setProperty(ExtendedSystemPropertyKeys.outputs.name(), serializeSignatures(signature.outputSignature()));
node.setProperty(ExtendedSystemPropertyKeys.mode.name(), signature.mode().name());
setLastUpdate(tx);
registerProcedure(signature, statement);
return null;
Expand Down Expand Up @@ -305,17 +306,17 @@ public static List<FieldSignature> deserializeSignatures(String s) {
}

private void setLastUpdate(Transaction tx) {
Node node = tx.findNode(SystemLabels.ApocCypherProceduresMeta, SystemPropertyKeys.database.name(), api.databaseName());
Node node = tx.findNode(ExtendedSystemLabels.ApocCypherProceduresMeta, SystemPropertyKeys.database.name(), api.databaseName());
if (node == null) {
node = tx.createNode(SystemLabels.ApocCypherProceduresMeta);
node = tx.createNode(ExtendedSystemLabels.ApocCypherProceduresMeta);
node.setProperty(SystemPropertyKeys.database.name(), api.databaseName());
}
node.setProperty(SystemPropertyKeys.lastUpdated.name(), System.currentTimeMillis());
}

private long getLastUpdate() {
return withSystemDb( tx -> {
Node node = tx.findNode(SystemLabels.ApocCypherProceduresMeta, SystemPropertyKeys.database.name(), api.databaseName());
Node node = tx.findNode(ExtendedSystemLabels.ApocCypherProceduresMeta, SystemPropertyKeys.database.name(), api.databaseName());
return node == null ? 0L : (long) node.getProperty(SystemPropertyKeys.lastUpdated.name());
});
}
Expand Down Expand Up @@ -600,11 +601,11 @@ public Map<String, Object> params(AnyValue[] input, List<FieldSignature> fieldSi
public void removeProcedure(String name) {
withSystemDb(tx -> {
QualifiedName qName = qualifiedName(name);
tx.findNodes(SystemLabels.ApocCypherProcedures,
tx.findNodes(ExtendedSystemLabels.ApocCypherProcedures,
SystemPropertyKeys.database.name(), api.databaseName(),
SystemPropertyKeys.name.name(), qName.name(),
SystemPropertyKeys.prefix.name(), qName.namespace()
).stream().filter(n -> n.hasLabel(SystemLabels.Procedure)).forEach(node -> {
ExtendedSystemPropertyKeys.prefix.name(), qName.namespace()
).stream().filter(n -> n.hasLabel(ExtendedSystemLabels.Procedure)).forEach(node -> {
ProcedureDescriptor descriptor = procedureDescriptor(node);
registerProcedure(descriptor.getSignature(), null);
node.delete();
Expand All @@ -617,11 +618,11 @@ public void removeProcedure(String name) {
public void removeFunction(String name) {
withSystemDb(tx -> {
QualifiedName qName = qualifiedName(name);
tx.findNodes(SystemLabels.ApocCypherProcedures,
tx.findNodes(ExtendedSystemLabels.ApocCypherProcedures,
SystemPropertyKeys.database.name(), api.databaseName(),
SystemPropertyKeys.name.name(), qName.name(),
SystemPropertyKeys.prefix.name(), qName.namespace()
).stream().filter(n -> n.hasLabel(SystemLabels.Function)).forEach(node -> {
ExtendedSystemPropertyKeys.prefix.name(), qName.namespace()
).stream().filter(n -> n.hasLabel(ExtendedSystemLabels.Function)).forEach(node -> {
UserFunctionDescriptor descriptor = userFunctionDescriptor(node);
registerFunction(descriptor.getSignature(), null, false);
node.delete();
Expand Down
6 changes: 3 additions & 3 deletions extended/src/main/java/apoc/cypher/CypherExtended.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import apoc.Extended;
import apoc.Pools;
import apoc.result.MapResult;
import apoc.util.CompressionAlgo;
import apoc.util.FileUtils;
import apoc.util.QueueBasedSpliterator;
import apoc.util.Util;
Expand Down Expand Up @@ -55,8 +56,7 @@
*/
@Extended
public class CypherExtended {

public static final String COMPILED_PREFIX = "CYPHER runtime="+ Util.COMPILED;
public static final String COMPILED_PREFIX = "CYPHER runtime=interpreted"; // todo handle enterprise properly
public static final int PARTITIONS = 100 * Runtime.getRuntime().availableProcessors();
public static final int MAX_BATCH = 10000;

Expand Down Expand Up @@ -259,7 +259,7 @@ public RowResult(long row, Map<String, Object> result) {
}
private Reader readerForFile(@Name("file") String fileName) {
try {
return FileUtils.readerFor(fileName);
return FileUtils.readerFor(fileName, CompressionAlgo.NONE.name());
} catch (IOException ioe) {
throw new RuntimeException("Error accessing file "+fileName,ioe);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,4 @@ public Stream<PathResult> queryAndLink(@Name("node") Node node,
.map(r -> new VirtualPath.Builder(r.getStartNode()).push(r).build())
.map(PathResult::new);
}

}
Loading