Browse Source

在不支持V8的服务器上切换为使用nashorn脚本引擎(性能较低且只支持ES5语法)

paid
richie 5 years ago
parent
commit
3365c7a506
  1. 4
      build.xml
  2. 3
      plugin.xml
  3. 77
      src/main/java/com/fr/plugin/db/redis/core/RedisScriptTableDataModel.java
  4. 16
      src/main/java/com/fr/plugin/db/redis/help/Console.java
  5. 1
      src/main/java/com/fr/plugin/db/redis/help/Files.java
  6. 107
      src/main/java/com/fr/plugin/db/redis/help/RedisClient.java
  7. 36
      src/main/java/com/fr/plugin/db/redis/help/RedisClientSelector.java
  8. 18
      src/main/java/com/fr/plugin/db/redis/help/ScriptBridge.java
  9. 41
      src/main/java/com/fr/plugin/db/redis/help/client/BaseRedisClient.java
  10. 172
      src/main/java/com/fr/plugin/db/redis/help/client/RedisNashornClient.java
  11. 171
      src/main/java/com/fr/plugin/db/redis/help/client/RedisV8Client.java
  12. 46
      src/main/java/com/fr/plugin/db/redis/help/client/SimpleDataModel.java
  13. 7
      src/main/java/com/fr/plugin/db/redis/util/RedisUtils.java

4
build.xml

@ -88,8 +88,8 @@
<param name="resources_from" value="${basedir}"/> <param name="resources_from" value="${basedir}"/>
</antcall> </antcall>
<antcall target="compile_javas"> <antcall target="compile_javas">
<param name="source_jdk_version" value="1.6"/> <param name="source_jdk_version" value="1.7"/>
<param name="target_jdk_version" value="1.6"/> <param name="target_jdk_version" value="1.7"/>
<param name="compile_jdk_version" value="${jdk.home}"/> <param name="compile_jdk_version" value="${jdk.home}"/>
<param name="compile_files" value="${basedir}/src"/> <param name="compile_files" value="${basedir}/src"/>
</antcall> </antcall>

3
plugin.xml

@ -3,12 +3,13 @@
<id>com.fr.solution.plugin.db.redis.v10</id> <id>com.fr.solution.plugin.db.redis.v10</id>
<name><![CDATA[Redis数据集]]></name> <name><![CDATA[Redis数据集]]></name>
<active>yes</active> <active>yes</active>
<version>6.0</version> <version>6.1</version>
<env-version>10.0</env-version> <env-version>10.0</env-version>
<jartime>2018-11-29</jartime> <jartime>2018-11-29</jartime>
<vendor>richie</vendor> <vendor>richie</vendor>
<description><![CDATA[可以连接Redis数据库,支持哈希表、列表、集合以及有序集合]]></description> <description><![CDATA[可以连接Redis数据库,支持哈希表、列表、集合以及有序集合]]></description>
<change-notes><![CDATA[ <change-notes><![CDATA[
[2019-08-26]不支持V8引擎的机器上使用JDK内置的脚本引擎(仅支持ES5语法)。<br/>
[2019-03-21]现在可以通过跳板服务连接redis。<br/> [2019-03-21]现在可以通过跳板服务连接redis。<br/>
[2019-03-18]修复连接没有释放的问题。<br/> [2019-03-18]修复连接没有释放的问题。<br/>
[2019-03-18]增加程序数据集,可以使用javascript进行取数,需要2019-03-01之后的版本。<br/> [2019-03-18]增加程序数据集,可以使用javascript进行取数,需要2019-03-01之后的版本。<br/>

77
src/main/java/com/fr/plugin/db/redis/core/RedisScriptTableDataModel.java

@ -1,18 +1,11 @@
package com.fr.plugin.db.redis.core; package com.fr.plugin.db.redis.core;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import com.fr.base.TableData;
import com.fr.data.AbstractDataModel; import com.fr.data.AbstractDataModel;
import com.fr.plugin.db.redis.core.emb.Redis; import com.fr.plugin.db.redis.core.emb.Redis;
import com.fr.plugin.db.redis.help.Console;
import com.fr.plugin.db.redis.help.Files;
import com.fr.plugin.db.redis.help.RedisClient; import com.fr.plugin.db.redis.help.RedisClient;
import com.fr.plugin.db.redis.util.RedisUtils; import com.fr.plugin.db.redis.help.RedisClientSelector;
import com.fr.third.redis.clients.jedis.Jedis; import com.fr.plugin.db.redis.help.client.SimpleDataModel;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -43,69 +36,15 @@ public class RedisScriptTableDataModel extends AbstractDataModel {
} }
Redis redis = mc.createRedisClient(); Redis redis = mc.createRedisClient();
redis.getClient().select(dbIndex); redis.getClient().select(dbIndex);
V8 v8 = V8.createV8Runtime(); RedisClient redisClient = RedisClientSelector.select(redis);
RedisClient client = new RedisClient(v8, redis.getClient()); SimpleDataModel simple = redisClient.build(redis, script, rowCount);
V8Object v8Console = initConsole(v8); if (simple != null) {
V8Object v8Require = initRequire(v8); this.columnNames = simple.getColumnNames();
V8Object v8Client = initRedis(v8, client); this.data = simple.getData();
this.rowCount = simple.getRowCount();
v8.executeVoidScript(
"function unique(array) {return Array.from(new Set(array));};" +
"function merge(table, column) {return {content:table, column:column}};");
V8Object returnObj = v8.executeObjectScript(String.format("(function(){%s})();", script));
V8Array v8Column = returnObj.getArray("column");
V8Array v8Table = returnObj.getArray("content");
int columnCount = v8Column.length();
columnNames = new String[columnCount];
for (int i = 0; i < columnCount; i++) {
columnNames[i] = String.valueOf(v8Column.get(i));
} }
int returnRowCount = v8Table.length();
int realCount = rowCount == TableData.RESULT_ALL ? returnRowCount : Math.min(returnRowCount, this.rowCount);
for (int i = 0; i < realCount; i++) {
V8Array v8Row = v8Table.getArray(i);
List<Object> row = new ArrayList<Object>();
for (int j = 0, col = v8Row.length(); j < col; j++) {
row.add(v8Row.get(j));
}
v8Row.release();
data.add(row);
}
redis.close();
v8Table.release();
v8Column.release();
returnObj.release();
v8Client.release();
v8Require.release();
v8Console.release();
v8.release(true);
} }
private V8Object initConsole(V8 v8) {
V8Object v8Console = new V8Object(v8);
v8.add("console", v8Console);
Console console = new Console(v8);
RedisUtils.registerJavaMethods(v8Console, console);
return v8Console;
}
private V8Object initRequire(V8 v8) {
V8Object v8Files = new V8Object(v8);
v8.add("Files", v8Files);
Files console = new Files(v8);
RedisUtils.registerJavaMethods(v8Files, console);
return v8Files;
}
private V8Object initRedis(final V8 v8, final RedisClient client) {
V8Object v8Client = new V8Object(v8);
v8.add("redis", v8Client);
RedisUtils.registerJavaMethods(v8Client, client);
return v8Client;
}
@Override @Override
public int getColumnCount() { public int getColumnCount() {

16
src/main/java/com/fr/plugin/db/redis/help/Console.java

@ -1,16 +1,6 @@
package com.fr.plugin.db.redis.help; package com.fr.plugin.db.redis.help;
import com.eclipsesource.v8.V8;
import com.fr.general.IOUtils;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
/** /**
* @author richie * @author richie
@ -19,16 +9,16 @@ import java.io.UnsupportedEncodingException;
*/ */
public class Console { public class Console {
private V8 v8; public Console() {
public Console(V8 v8) {
this.v8 = v8;
} }
@ScriptBridge
public void log(Object message) { public void log(Object message) {
FineLoggerFactory.getLogger().info(message == null ? null : message.toString()); FineLoggerFactory.getLogger().info(message == null ? null : message.toString());
} }
@ScriptBridge
public void error(Object message) { public void error(Object message) {
FineLoggerFactory.getLogger().error(message == null ? null : message.toString()); FineLoggerFactory.getLogger().error(message == null ? null : message.toString());
} }

1
src/main/java/com/fr/plugin/db/redis/help/Files.java

@ -21,6 +21,7 @@ public class Files {
this.v8 = v8; this.v8 = v8;
} }
@ScriptBridge
public void require(String filePath) { public void require(String filePath) {
InputStream in = ResourceIOUtils.read(filePath); InputStream in = ResourceIOUtils.read(filePath);
if (in != null) { if (in != null) {

107
src/main/java/com/fr/plugin/db/redis/help/RedisClient.java

@ -1,102 +1,41 @@
package com.fr.plugin.db.redis.help; package com.fr.plugin.db.redis.help;
import com.eclipsesource.v8.V8; import com.fr.plugin.db.redis.core.emb.Redis;
import com.eclipsesource.v8.V8Array; import com.fr.plugin.db.redis.help.client.SimpleDataModel;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.utils.V8ObjectUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.third.redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* @author richie * @author richie
* @version 10.0 * @version 10.0
* Created by richie on 2019-03-18 * Created by richie on 2019-08-26
*/ */
public class RedisClient { public interface RedisClient<A, O> {
private Jedis jedis;
private V8 v8;
public RedisClient(V8 v8, Jedis jedis) { SimpleDataModel build(Redis redis, String query, int limit);
this.jedis = jedis;
this.v8 = v8;
}
public String get(String key) { @ScriptBridge
long start = System.currentTimeMillis(); String get(String key);
try {
return jedis.get(key);
} finally {
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
}
}
public String hget(String key, String field) { @ScriptBridge
long start = System.currentTimeMillis(); String hget(String key, String field);
try {
return jedis.hget(key, field);
} finally {
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
}
}
public V8Array hkeys(String key) { @ScriptBridge
long start = System.currentTimeMillis(); A hkeys(String key);
Set<String> set = jedis.keys(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set));
}
public V8Array hmget(String key, String... fields) { @ScriptBridge
long start = System.currentTimeMillis(); A hmget(String key, String... fields);
List<String> list = jedis.hmget(key, fields);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, list);
}
public V8Object hgetAll(String key) { @ScriptBridge
long start = System.currentTimeMillis(); O hgetAll(String key);
Map<String, String> map = jedis.hgetAll(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Object(v8, map);
}
public V8Array keys(String pattern) { @ScriptBridge
long start = System.currentTimeMillis(); A keys(String pattern);
Set<String> set = jedis.keys(pattern);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set));
}
public V8Array lrange(String key, long start, long end) { @ScriptBridge
long start0 = System.currentTimeMillis(); A lrange(String key, long start, long end);
List<String> list = jedis.lrange(key, start, end);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start0);
return V8ObjectUtils.toV8Array(v8, list);
}
public V8Array mget(V8Array keys) { @ScriptBridge
long start = System.currentTimeMillis(); A mget(A keys);
int len = keys.length();
String[] parameters = new String[len];
for (int i = 0; i < len; i ++) {
parameters[i] = keys.getString(i);
}
List<String> list = jedis.mget(parameters);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
keys.release();
return V8ObjectUtils.toV8Array(v8, list);
}
public V8Array smembers(String key) { @ScriptBridge
long start = System.currentTimeMillis(); A smembers(String key);
Set<String> set = jedis.smembers(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set));
}
} }

36
src/main/java/com/fr/plugin/db/redis/help/RedisClientSelector.java

@ -0,0 +1,36 @@
package com.fr.plugin.db.redis.help;
import com.eclipsesource.v8.V8;
import com.fr.plugin.db.redis.core.emb.Redis;
import com.fr.plugin.db.redis.help.client.RedisNashornClient;
import com.fr.plugin.db.redis.help.client.RedisV8Client;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-08-26
*/
public class RedisClientSelector {
private final static boolean SUPPORT_J2V8 = isSupportJ2v8();
private static boolean isSupportJ2v8() {
V8 v8;
try {
v8 = V8.createV8Runtime();
} catch (IllegalStateException ex) {
return false;
}
v8.release();
return true;
}
public static RedisClient select(Redis redis) {
if (SUPPORT_J2V8) {
return new RedisV8Client(redis.getClient());
} else {
return new RedisNashornClient(redis.getClient());
}
}
}

18
src/main/java/com/fr/plugin/db/redis/help/ScriptBridge.java

@ -0,0 +1,18 @@
package com.fr.plugin.db.redis.help;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-08-26
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ScriptBridge {
}

41
src/main/java/com/fr/plugin/db/redis/help/client/BaseRedisClient.java

@ -0,0 +1,41 @@
package com.fr.plugin.db.redis.help.client;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.db.redis.help.ScriptBridge;
import com.fr.plugin.db.redis.help.RedisClient;
import com.fr.third.redis.clients.jedis.Jedis;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-08-26
*/
public abstract class BaseRedisClient<A, O> implements RedisClient<A, O> {
Jedis jedis;
BaseRedisClient(Jedis jedis) {
this.jedis = jedis;
}
@ScriptBridge
public String get(String key) {
long start = System.currentTimeMillis();
try {
return jedis.get(key);
} finally {
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
}
}
@ScriptBridge
public String hget(String key, String field) {
long start = System.currentTimeMillis();
try {
return jedis.hget(key, field);
} finally {
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
}
}
}

172
src/main/java/com/fr/plugin/db/redis/help/client/RedisNashornClient.java

@ -0,0 +1,172 @@
package com.fr.plugin.db.redis.help.client;
import com.fr.base.TableData;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.db.redis.core.emb.Redis;
import com.fr.plugin.db.redis.help.Console;
import com.fr.plugin.db.redis.help.ScriptBridge;
import com.fr.third.redis.clients.jedis.Jedis;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-08-26
*/
public class RedisNashornClient extends BaseRedisClient<Object[], Map<Object, Object>> {
private static final String PREPARE_SCRIPT =
"function unique(array) {var res = [];for (var i = 0, arrayLen = array.length; i < arrayLen; i++) {for (var j = 0, resLen = res.length; j < resLen; j++ ) {if (array[i] === res[j]) {break;}} if (j === resLen) {res.push(array[i])}} return res;}\n" +
"function merge(table, column) {return {content:table, column:column}};";
private ScriptEngine scriptEngine;
public RedisNashornClient(Jedis jedis) {
super(jedis);
this.scriptEngine = findScriptEngine();
}
@Override
@ScriptBridge
public Object[] hkeys(String key) {
long start = System.currentTimeMillis();
Set<String> set = jedis.keys(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return set.toArray(new String[0]);
}
@Override
@ScriptBridge
public Object[] hmget(String key, String... fields) {
long start = System.currentTimeMillis();
List<String> list = jedis.hmget(key, fields);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return list.toArray(new String[0]);
}
@Override
@ScriptBridge
public Map<Object, Object> hgetAll(String key) {
long start = System.currentTimeMillis();
Map<String, String> map = jedis.hgetAll(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return new TreeMap<Object, Object>(map);
}
@Override
@ScriptBridge
public Object[] keys(String pattern) {
long start = System.currentTimeMillis();
Set<String> set = jedis.keys(pattern);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return set.toArray(new String[0]);
}
@Override
@ScriptBridge
public Object[] lrange(String key, long start, long end) {
long start0 = System.currentTimeMillis();
List<String> list = jedis.lrange(key, start, end);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start0);
return list.toArray(new String[0]);
}
@Override
@ScriptBridge
public Object[] mget(Object[] keys) {
long start = System.currentTimeMillis();
int len = keys.length;
String[] parameters = new String[len];
for (int i = 0; i < len; i ++) {
parameters[i] = String.valueOf(keys[i]);
}
List<String> list = jedis.mget(parameters);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return list.toArray(new String[0]);
}
@Override
@ScriptBridge
public Object[] smembers(String key) {
long start = System.currentTimeMillis();
Set<String> set = jedis.smembers(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return set.toArray(new String[0]);
}
@Override
public SimpleDataModel build(Redis redis, String query, int limit) {
scriptEngine.put("console", new Console());
scriptEngine.put("redis", new RedisNashornClient(redis.getClient()));
try {
scriptEngine.eval(PREPARE_SCRIPT);
Map<String, Map<String, Object>> r = (Map<String, Map<String, Object>>) scriptEngine.eval("(function(){" + query + "})();");
Map<String, Object> columns = r.get("column");
int columnCount = columns.size();
String[] columnNames = new String[columnCount];
int k = 0;
for (Map.Entry<String, Object> entry : columns.entrySet()) {
columnNames[k] = String.valueOf(entry.getValue());
k++;
}
Map<String, Object> content = r.get("content");
int returnRowCount = content.size();
int realCount = limit == TableData.RESULT_ALL ? returnRowCount : Math.min(returnRowCount, limit);
List<List<Object>> data = new ArrayList<List<Object>>();
int i = 0;
for (Map.Entry<String, Object> entry : content.entrySet()) {
if (i >= realCount) {
break;
}
List<Object> row = new ArrayList<Object>();
Object el = entry.getValue();
if (el instanceof Map) {
Map<String, Object> rowCollection = (Map<String, Object>)entry.getValue();
for (Map.Entry<String, Object> rowEntry : rowCollection.entrySet()) {
row.add(rowEntry.getValue());
}
} else if (el instanceof Object[]) {
Object[] array = (Object[])el;
row.addAll(Arrays.asList(array));
}
data.add(row);
i++;
}
return new SimpleDataModel(columnNames, data, realCount);
} catch (ScriptException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
private static ScriptEngine findScriptEngine() {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine engine = scriptEngineManager.getEngineByName("nashorn");
if(engine == null) {
List<ScriptEngineFactory> factories = scriptEngineManager.getEngineFactories();
for (ScriptEngineFactory factory : factories) {
ScriptEngine current = factory.getScriptEngine();
if (current != null) {
engine = current;
}
}
}
return engine;
}
}

171
src/main/java/com/fr/plugin/db/redis/help/client/RedisV8Client.java

@ -0,0 +1,171 @@
package com.fr.plugin.db.redis.help.client;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.utils.V8ObjectUtils;
import com.fr.base.TableData;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.db.redis.core.emb.Redis;
import com.fr.plugin.db.redis.help.Console;
import com.fr.plugin.db.redis.help.Files;
import com.fr.plugin.db.redis.help.ScriptBridge;
import com.fr.plugin.db.redis.util.RedisUtils;
import com.fr.third.redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-18
*/
public class RedisV8Client extends BaseRedisClient<V8Array, V8Object> {
private V8 v8;
public RedisV8Client(Jedis jedis) {
super(jedis);
this.v8 = V8.createV8Runtime();
}
@Override
@ScriptBridge
public V8Array hkeys(String key) {
long start = System.currentTimeMillis();
Set<String> set = jedis.keys(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set));
}
@Override
@ScriptBridge
public V8Array hmget(String key, String... fields) {
long start = System.currentTimeMillis();
List<String> list = jedis.hmget(key, fields);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, list);
}
@Override
@ScriptBridge
public V8Object hgetAll(String key) {
long start = System.currentTimeMillis();
Map<String, String> map = jedis.hgetAll(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Object(v8, map);
}
@Override
@ScriptBridge
public V8Array keys(String pattern) {
long start = System.currentTimeMillis();
Set<String> set = jedis.keys(pattern);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set));
}
@Override
@ScriptBridge
public V8Array lrange(String key, long start, long end) {
long start0 = System.currentTimeMillis();
List<String> list = jedis.lrange(key, start, end);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start0);
return V8ObjectUtils.toV8Array(v8, list);
}
@Override
@ScriptBridge
public V8Array mget(V8Array keys) {
long start = System.currentTimeMillis();
int len = keys.length();
String[] parameters = new String[len];
for (int i = 0; i < len; i ++) {
parameters[i] = keys.getString(i);
}
List<String> list = jedis.mget(parameters);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
keys.release();
return V8ObjectUtils.toV8Array(v8, list);
}
@Override
@ScriptBridge
public V8Array smembers(String key) {
long start = System.currentTimeMillis();
Set<String> set = jedis.smembers(key);
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start);
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set));
}
@Override
public SimpleDataModel build(Redis redis, String script, int limit) {
RedisV8Client client = new RedisV8Client(redis.getClient());
V8Object v8Console = initConsole(v8);
V8Object v8Require = initRequire(v8);
V8Object v8Client = initRedis(v8, client);
v8.executeVoidScript(
"function unique(array) {return Array.from(new Set(array));};" +
"function merge(table, column) {return {content:table, column:column}};");
V8Object returnObj = v8.executeObjectScript(String.format("(function(){%s})();", script));
V8Array v8Column = returnObj.getArray("column");
V8Array v8Table = returnObj.getArray("content");
int columnCount = v8Column.length();
String[] columnNames = new String[columnCount];
for (int i = 0; i < columnCount; i++) {
columnNames[i] = String.valueOf(v8Column.get(i));
}
int returnRowCount = v8Table.length();
int realCount = limit == TableData.RESULT_ALL ? returnRowCount : Math.min(returnRowCount, limit);
List<List<Object>> data = new ArrayList<List<Object>>();
for (int i = 0; i < realCount; i++) {
V8Array v8Row = v8Table.getArray(i);
List<Object> row = new ArrayList<Object>();
for (int j = 0, col = v8Row.length(); j < col; j++) {
row.add(v8Row.get(j));
}
v8Row.release();
data.add(row);
}
redis.close();
v8Table.release();
v8Column.release();
returnObj.release();
v8Client.release();
v8Require.release();
v8Console.release();
v8.release(true);
return new SimpleDataModel(columnNames, data, realCount);
}
private V8Object initConsole(V8 v8) {
V8Object v8Console = new V8Object(v8);
v8.add("console", v8Console);
Console console = new Console();
RedisUtils.registerJavaMethods(v8Console, console);
return v8Console;
}
private V8Object initRequire(V8 v8) {
V8Object v8Files = new V8Object(v8);
v8.add("Files", v8Files);
Files console = new Files(v8);
RedisUtils.registerJavaMethods(v8Files, console);
return v8Files;
}
private V8Object initRedis(final V8 v8, final RedisV8Client client) {
V8Object v8Client = new V8Object(v8);
v8.add("redis", v8Client);
RedisUtils.registerJavaMethods(v8Client, client);
return v8Client;
}
}

46
src/main/java/com/fr/plugin/db/redis/help/client/SimpleDataModel.java

@ -0,0 +1,46 @@
package com.fr.plugin.db.redis.help.client;
import java.util.ArrayList;
import java.util.List;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-08-26
*/
public class SimpleDataModel {
private int rowCount;
private List<List<Object>> data = new ArrayList<List<Object>>();
private String[] columnNames = null;
SimpleDataModel(String[] columnNames, List<List<Object>> data, int rowCount){
this.columnNames = columnNames;
this.data = data;
this.rowCount = rowCount;
}
public int getRowCount() {
return rowCount;
}
public void setRowCount(int rowCount) {
this.rowCount = rowCount;
}
public List<List<Object>> getData() {
return data;
}
public void setData(List<List<Object>> data) {
this.data = data;
}
public String[] getColumnNames() {
return columnNames;
}
public void setColumnNames(String[] columnNames) {
this.columnNames = columnNames;
}
}

7
src/main/java/com/fr/plugin/db/redis/util/RedisUtils.java

@ -3,6 +3,7 @@ package com.fr.plugin.db.redis.util;
import com.eclipsesource.v8.V8Object; import com.eclipsesource.v8.V8Object;
import com.fr.base.Parameter; import com.fr.base.Parameter;
import com.fr.base.TemplateUtils; import com.fr.base.TemplateUtils;
import com.fr.plugin.db.redis.help.ScriptBridge;
import com.fr.stable.ArrayUtils; import com.fr.stable.ArrayUtils;
import com.fr.third.redis.clients.jedis.Jedis; import com.fr.third.redis.clients.jedis.Jedis;
@ -41,9 +42,11 @@ public class RedisUtils {
} }
public static void registerJavaMethods(V8Object v8Object, Object target) { public static void registerJavaMethods(V8Object v8Object, Object target) {
Method[] methods = target.getClass().getDeclaredMethods(); Method[] methods = target.getClass().getMethods();
for (Method m : methods) { for (Method m : methods) {
v8Object.registerJavaMethod(target, m.getName(), m.getName(), m.getParameterTypes()); if (m.getAnnotation(ScriptBridge.class) != null) {
v8Object.registerJavaMethod(target, m.getName(), m.getName(), m.getParameterTypes());
}
} }
} }
} }

Loading…
Cancel
Save