Skip to content

Commit

Permalink
[gRNAet7B] Changes from neo4j/apoc#250
Browse files Browse the repository at this point in the history
  • Loading branch information
vga91 committed Jan 9, 2023
1 parent 420d24a commit f01e18a
Show file tree
Hide file tree
Showing 12 changed files with 319 additions and 176 deletions.
1 change: 0 additions & 1 deletion core/src/main/java/apoc/trigger/Trigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.Map;
import java.util.stream.Stream;

import static apoc.trigger.TriggerNewProcedures.TriggerInfo;
/**
* @author mh
* @since 20.09.16
Expand Down
68 changes: 26 additions & 42 deletions core/src/main/java/apoc/trigger/TriggerHandlerNewProcedures.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,21 @@
import org.neo4j.graphdb.Transaction;
import org.neo4j.internal.helpers.collection.Pair;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Stream;

import static apoc.ApocConfig.APOC_TRIGGER_ENABLED;
import static apoc.ApocConfig.apocConfig;
import static apoc.trigger.TriggerInfo.fromNode;

public class TriggerHandlerNewProcedures {
public static final String NOT_ENABLED_ERROR = "Triggers have not been enabled." +
" Set 'apoc.trigger.enabled=true' in your apoc.conf file located in the $NEO4J_HOME/conf/ directory.";

private static Map<String, Object> toTriggerInfo(Node node) {
return node.getAllProperties()
.entrySet().stream()
.filter(e -> !SystemPropertyKeys.database.name().equals(e.getKey()))
.collect(HashMap::new, // workaround for https://bugs.openjdk.java.net/browse/JDK-8148463
(mapAccumulator, e) -> {
Object value = List.of(SystemPropertyKeys.selector.name(), SystemPropertyKeys.params.name()).contains(e.getKey())
? Util.fromJson((String) e.getValue(), Map.class)
: e.getValue();

mapAccumulator.put(e.getKey(), value);
}, HashMap::putAll);
}

private static boolean isEnabled() {
return apocConfig().getBoolean(APOC_TRIGGER_ENABLED);
Expand All @@ -45,89 +34,84 @@ public static void checkEnabled() {
}
}

public static Map<String, Object> install(String databaseName, String triggerName, String statement, Map<String,Object> selector, Map<String,Object> params) {
final HashMap<String, Object> previous = new HashMap<>();
public static TriggerInfo install(String databaseName, String triggerName, String statement, Map<String,Object> selector, Map<String,Object> params) {
AtomicReference<TriggerInfo> previous = new AtomicReference<>();

withSystemDb(tx -> {
Node node = Util.mergeNode(tx, SystemLabels.ApocTrigger, null,
Pair.of(SystemPropertyKeys.database.name(), databaseName),
Pair.of(SystemPropertyKeys.name.name(), triggerName));

// we'll return previous trigger info
previous.putAll(toTriggerInfo(node));
previous.set( fromNode(node, true) );

node.setProperty(SystemPropertyKeys.statement.name(), statement);
node.setProperty(SystemPropertyKeys.selector.name(), Util.toJson(selector));
node.setProperty(SystemPropertyKeys.params.name(), Util.toJson(params));
node.setProperty(SystemPropertyKeys.paused.name(), false);

setLastUpdate(databaseName, tx);
return null;
});

return previous;
return previous.get();
}

public static Map<String, Object> drop(String databaseName, String triggerName) {
final HashMap<String, Object> previous = new HashMap<>();
public static TriggerInfo drop(String databaseName, String triggerName) {
AtomicReference<TriggerInfo> previous = new AtomicReference<>();

withSystemDb(tx -> {
getTriggerNodes(databaseName, tx, triggerName)
.forEachRemaining(node -> {
previous.putAll(toTriggerInfo(node));
previous.set( fromNode(node, false) );
node.delete();
});

setLastUpdate(databaseName, tx);
return null;
});

return previous;
return previous.get();
}

public static Map<String, Object> updatePaused(String databaseName, String name, boolean paused) {
HashMap<String, Object> result = new HashMap<>();
public static TriggerInfo updatePaused(String databaseName, String name, boolean paused) {
AtomicReference<TriggerInfo> result = new AtomicReference<>();

withSystemDb(tx -> {
getTriggerNodes(databaseName, tx, name)
.forEachRemaining(node -> {
node.setProperty( SystemPropertyKeys.paused.name(), paused );

// we'll return previous trigger info
result.putAll(toTriggerInfo(node));
result.set( fromNode(node, true) );
});

setLastUpdate(databaseName, tx);
return null;
});

return result;
return result.get();
}

public static Map<String, Object> dropAll(String databaseName) {
HashMap<String, Object> previous = new HashMap<>();
public static List<TriggerInfo> dropAll(String databaseName) {
final List<TriggerInfo> previous = new ArrayList<>();

withSystemDb(tx -> {
getTriggerNodes(databaseName, tx)
.forEachRemaining(node -> {
String triggerName = (String) node.getProperty(SystemPropertyKeys.name.name());

// we'll return previous trigger info
previous.put(triggerName, toTriggerInfo(node));
previous.add( fromNode(node, false) );
node.delete();
});
setLastUpdate(databaseName, tx);
return null;
});

return previous;
}

public static List<Map<String, Object>> getTriggerNodesList(String databaseName, Transaction tx) {
public static Stream<TriggerInfo> getTriggerNodesList(String databaseName, Transaction tx) {
return getTriggerNodes(databaseName, tx)
.stream()
.map(TriggerHandlerNewProcedures::toTriggerInfo)
.collect(Collectors.toList());
.map(trigger -> fromNode(trigger, true));
}

public static ResourceIterator<Node> getTriggerNodes(String databaseName, Transaction tx) {
Expand All @@ -144,11 +128,10 @@ public static ResourceIterator<Node> getTriggerNodes(String databaseName, Transa
SystemPropertyKeys.name.name(), name);
}

public static <T> T withSystemDb(Function<Transaction, T> action) {
public static void withSystemDb(Consumer<Transaction> consumer) {
try (Transaction tx = apocConfig().getSystemDb().beginTx()) {
T result = action.apply(tx);
consumer.accept(tx);
tx.commit();
return result;
}
}

Expand All @@ -158,7 +141,8 @@ private static void setLastUpdate(String databaseName, Transaction tx) {
node = tx.createNode(SystemLabels.ApocTriggerMeta);
node.setProperty(SystemPropertyKeys.database.name(), databaseName);
}
node.setProperty(SystemPropertyKeys.lastUpdated.name(), System.currentTimeMillis());
final long value = System.currentTimeMillis();
node.setProperty(SystemPropertyKeys.lastUpdated.name(), value);
}

}
75 changes: 75 additions & 0 deletions core/src/main/java/apoc/trigger/TriggerInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package apoc.trigger;

import apoc.SystemPropertyKeys;
import apoc.util.Util;
import org.neo4j.graphdb.Node;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TriggerInfo {
public String name;
public String query;
public Map<String, Object> selector;
public Map<String, Object> params;
public boolean installed = false;
public boolean paused = false;

public TriggerInfo(String name) {
this.name = name;
}

public TriggerInfo(String name, String query) {
this(name);
this.query = query;
}

public TriggerInfo(String name, String query, Map<String, Object> selector, boolean installed, boolean paused) {
this(name, query);
this.selector = selector;
this.installed = installed;
this.paused = paused;
}


public TriggerInfo(String name, String query, Map<String, Object> selector, Map<String, Object> params, boolean installed, boolean paused) {
this(name, query, selector, installed, paused);
this.params = params;
}

public static TriggerInfo from(Map<String, Object> mapInfo, boolean installed, String name) {
return new TriggerInfo(name,
(String) mapInfo.get(SystemPropertyKeys.statement.name()),
(Map<String, Object>) mapInfo.get(SystemPropertyKeys.selector.name()),
(Map<String, Object>) mapInfo.get(SystemPropertyKeys.params.name()),
installed,
(boolean) mapInfo.getOrDefault(SystemPropertyKeys.paused.name(), true));
}

public static TriggerInfo from(Map<String, Object> mapInfo, boolean installed) {
return from(mapInfo, installed, (String) mapInfo.get(SystemPropertyKeys.name.name()));
}

public static TriggerInfo fromNode(Node node, boolean installed) {
// filter and transform node props to map
final Map<String, Object> triggerMap = toTriggerMap(node);

// transform map to TriggerInfo
return from(triggerMap, installed);
}

private static Map<String, Object> toTriggerMap(Node node) {
return node.getAllProperties()
.entrySet().stream()
.filter(e -> !SystemPropertyKeys.database.name().equals(e.getKey()))
.collect(HashMap::new, // workaround for https://bugs.openjdk.java.net/browse/JDK-8148463
(mapAccumulator, e) -> {
Object value = List.of(SystemPropertyKeys.selector.name(), SystemPropertyKeys.params.name()).contains(e.getKey())
? Util.fromJson((String) e.getValue(), Map.class)
: e.getValue();

mapAccumulator.put(e.getKey(), value);
}, HashMap::putAll);
}
}
Loading

0 comments on commit f01e18a

Please sign in to comment.