From 3365c7a50660a06b63c2897a2f4f5f6c84136505 Mon Sep 17 00:00:00 2001 From: richie Date: Mon, 26 Aug 2019 18:48:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E4=B8=8D=E6=94=AF=E6=8C=81V8=E7=9A=84?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E4=B8=8A=E5=88=87=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?=E4=BD=BF=E7=94=A8nashorn=E8=84=9A=E6=9C=AC=E5=BC=95=E6=93=8E?= =?UTF-8?q?=EF=BC=88=E6=80=A7=E8=83=BD=E8=BE=83=E4=BD=8E=E4=B8=94=E5=8F=AA?= =?UTF-8?q?=E6=94=AF=E6=8C=81ES5=E8=AF=AD=E6=B3=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.xml | 4 +- plugin.xml | 3 +- .../redis/core/RedisScriptTableDataModel.java | 77 +------- .../com/fr/plugin/db/redis/help/Console.java | 16 +- .../com/fr/plugin/db/redis/help/Files.java | 1 + .../fr/plugin/db/redis/help/RedisClient.java | 107 +++-------- .../db/redis/help/RedisClientSelector.java | 36 ++++ .../fr/plugin/db/redis/help/ScriptBridge.java | 18 ++ .../db/redis/help/client/BaseRedisClient.java | 41 +++++ .../redis/help/client/RedisNashornClient.java | 172 ++++++++++++++++++ .../db/redis/help/client/RedisV8Client.java | 171 +++++++++++++++++ .../db/redis/help/client/SimpleDataModel.java | 46 +++++ .../fr/plugin/db/redis/util/RedisUtils.java | 7 +- 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 src/main/java/com/fr/plugin/db/redis/help/RedisClientSelector.java create mode 100644 src/main/java/com/fr/plugin/db/redis/help/ScriptBridge.java create mode 100644 src/main/java/com/fr/plugin/db/redis/help/client/BaseRedisClient.java create mode 100644 src/main/java/com/fr/plugin/db/redis/help/client/RedisNashornClient.java create mode 100644 src/main/java/com/fr/plugin/db/redis/help/client/RedisV8Client.java create mode 100644 src/main/java/com/fr/plugin/db/redis/help/client/SimpleDataModel.java diff --git a/build.xml b/build.xml index 80bc907..244edb0 100644 --- a/build.xml +++ b/build.xml @@ -88,8 +88,8 @@ - - + + diff --git a/plugin.xml b/plugin.xml index fde589c..b1a2a00 100755 --- a/plugin.xml +++ b/plugin.xml @@ -3,12 +3,13 @@ com.fr.solution.plugin.db.redis.v10 yes - 6.0 + 6.1 10.0 2018-11-29 richie [2019-03-21]现在可以通过跳板服务连接redis。
[2019-03-18]修复连接没有释放的问题。
[2019-03-18]增加程序数据集,可以使用javascript进行取数,需要2019-03-01之后的版本。
diff --git a/src/main/java/com/fr/plugin/db/redis/core/RedisScriptTableDataModel.java b/src/main/java/com/fr/plugin/db/redis/core/RedisScriptTableDataModel.java index f163ac8..29267b0 100644 --- a/src/main/java/com/fr/plugin/db/redis/core/RedisScriptTableDataModel.java +++ b/src/main/java/com/fr/plugin/db/redis/core/RedisScriptTableDataModel.java @@ -1,18 +1,11 @@ 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.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.util.RedisUtils; -import com.fr.third.redis.clients.jedis.Jedis; +import com.fr.plugin.db.redis.help.RedisClientSelector; +import com.fr.plugin.db.redis.help.client.SimpleDataModel; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @@ -43,69 +36,15 @@ public class RedisScriptTableDataModel extends AbstractDataModel { } Redis redis = mc.createRedisClient(); redis.getClient().select(dbIndex); - V8 v8 = V8.createV8Runtime(); - RedisClient client = new RedisClient(v8, 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(); - columnNames = new String[columnCount]; - for (int i = 0; i < columnCount; i++) { - columnNames[i] = String.valueOf(v8Column.get(i)); + RedisClient redisClient = RedisClientSelector.select(redis); + SimpleDataModel simple = redisClient.build(redis, script, rowCount); + if (simple != null) { + this.columnNames = simple.getColumnNames(); + this.data = simple.getData(); + this.rowCount = simple.getRowCount(); } - 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 row = new ArrayList(); - 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 public int getColumnCount() { diff --git a/src/main/java/com/fr/plugin/db/redis/help/Console.java b/src/main/java/com/fr/plugin/db/redis/help/Console.java index c7a3669..38d4813 100644 --- a/src/main/java/com/fr/plugin/db/redis/help/Console.java +++ b/src/main/java/com/fr/plugin/db/redis/help/Console.java @@ -1,16 +1,6 @@ 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.stable.EncodeConstants; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; /** * @author richie @@ -19,16 +9,16 @@ import java.io.UnsupportedEncodingException; */ public class Console { - private V8 v8; + public Console() { - public Console(V8 v8) { - this.v8 = v8; } + @ScriptBridge public void log(Object message) { FineLoggerFactory.getLogger().info(message == null ? null : message.toString()); } + @ScriptBridge public void error(Object message) { FineLoggerFactory.getLogger().error(message == null ? null : message.toString()); } diff --git a/src/main/java/com/fr/plugin/db/redis/help/Files.java b/src/main/java/com/fr/plugin/db/redis/help/Files.java index 8e34ab6..8420e00 100644 --- a/src/main/java/com/fr/plugin/db/redis/help/Files.java +++ b/src/main/java/com/fr/plugin/db/redis/help/Files.java @@ -21,6 +21,7 @@ public class Files { this.v8 = v8; } + @ScriptBridge public void require(String filePath) { InputStream in = ResourceIOUtils.read(filePath); if (in != null) { diff --git a/src/main/java/com/fr/plugin/db/redis/help/RedisClient.java b/src/main/java/com/fr/plugin/db/redis/help/RedisClient.java index 6dc6bd0..6361311 100644 --- a/src/main/java/com/fr/plugin/db/redis/help/RedisClient.java +++ b/src/main/java/com/fr/plugin/db/redis/help/RedisClient.java @@ -1,102 +1,41 @@ package com.fr.plugin.db.redis.help; -import com.eclipsesource.v8.V8; -import com.eclipsesource.v8.V8Array; -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; +import com.fr.plugin.db.redis.core.emb.Redis; +import com.fr.plugin.db.redis.help.client.SimpleDataModel; /** * @author richie * @version 10.0 - * Created by richie on 2019-03-18 + * Created by richie on 2019-08-26 */ -public class RedisClient { - - private Jedis jedis; - private V8 v8; +public interface RedisClient { - public RedisClient(V8 v8, Jedis jedis) { - this.jedis = jedis; - this.v8 = v8; - } + SimpleDataModel build(Redis redis, String query, int limit); - 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 + String get(String key); - 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); - } - } + @ScriptBridge + String hget(String key, String field); - public V8Array hkeys(String key) { - long start = System.currentTimeMillis(); - Set set = jedis.keys(key); - FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); - return V8ObjectUtils.toV8Array(v8, new ArrayList(set)); - } + @ScriptBridge + A hkeys(String key); - public V8Array hmget(String key, String... fields) { - long start = System.currentTimeMillis(); - List list = jedis.hmget(key, fields); - FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); - return V8ObjectUtils.toV8Array(v8, list); - } + @ScriptBridge + A hmget(String key, String... fields); - public V8Object hgetAll(String key) { - long start = System.currentTimeMillis(); - Map map = jedis.hgetAll(key); - FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); - return V8ObjectUtils.toV8Object(v8, map); - } + @ScriptBridge + O hgetAll(String key); - public V8Array keys(String pattern) { - long start = System.currentTimeMillis(); - Set set = jedis.keys(pattern); - FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); - return V8ObjectUtils.toV8Array(v8, new ArrayList(set)); - } + @ScriptBridge + A keys(String pattern); - public V8Array lrange(String key, long start, long end) { - long start0 = System.currentTimeMillis(); - List list = jedis.lrange(key, start, end); - FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start0); - return V8ObjectUtils.toV8Array(v8, list); - } + @ScriptBridge + A lrange(String key, long start, long end); - 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 list = jedis.mget(parameters); - FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); - keys.release(); - return V8ObjectUtils.toV8Array(v8, list); - } + @ScriptBridge + A mget(A keys); - public V8Array smembers(String key) { - long start = System.currentTimeMillis(); - Set set = jedis.smembers(key); - FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); - return V8ObjectUtils.toV8Array(v8, new ArrayList(set)); - } + @ScriptBridge + A smembers(String key); } diff --git a/src/main/java/com/fr/plugin/db/redis/help/RedisClientSelector.java b/src/main/java/com/fr/plugin/db/redis/help/RedisClientSelector.java new file mode 100644 index 0000000..97284b1 --- /dev/null +++ b/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()); + } + } + +} diff --git a/src/main/java/com/fr/plugin/db/redis/help/ScriptBridge.java b/src/main/java/com/fr/plugin/db/redis/help/ScriptBridge.java new file mode 100644 index 0000000..b67a253 --- /dev/null +++ b/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 { +} diff --git a/src/main/java/com/fr/plugin/db/redis/help/client/BaseRedisClient.java b/src/main/java/com/fr/plugin/db/redis/help/client/BaseRedisClient.java new file mode 100644 index 0000000..16a82e8 --- /dev/null +++ b/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 implements RedisClient { + + 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); + } + } + +} diff --git a/src/main/java/com/fr/plugin/db/redis/help/client/RedisNashornClient.java b/src/main/java/com/fr/plugin/db/redis/help/client/RedisNashornClient.java new file mode 100644 index 0000000..89a02b4 --- /dev/null +++ b/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> { + + 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 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 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 hgetAll(String key) { + long start = System.currentTimeMillis(); + Map map = jedis.hgetAll(key); + FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); + return new TreeMap(map); + } + + @Override + @ScriptBridge + public Object[] keys(String pattern) { + long start = System.currentTimeMillis(); + Set 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 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 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 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> r = (Map>) scriptEngine.eval("(function(){" + query + "})();"); + + Map columns = r.get("column"); + int columnCount = columns.size(); + String[] columnNames = new String[columnCount]; + int k = 0; + for (Map.Entry entry : columns.entrySet()) { + columnNames[k] = String.valueOf(entry.getValue()); + k++; + } + + Map content = r.get("content"); + int returnRowCount = content.size(); + int realCount = limit == TableData.RESULT_ALL ? returnRowCount : Math.min(returnRowCount, limit); + + List> data = new ArrayList>(); + int i = 0; + for (Map.Entry entry : content.entrySet()) { + if (i >= realCount) { + break; + } + List row = new ArrayList(); + + Object el = entry.getValue(); + if (el instanceof Map) { + Map rowCollection = (Map)entry.getValue(); + for (Map.Entry 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 factories = scriptEngineManager.getEngineFactories(); + for (ScriptEngineFactory factory : factories) { + ScriptEngine current = factory.getScriptEngine(); + if (current != null) { + engine = current; + } + } + } + return engine; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/help/client/RedisV8Client.java b/src/main/java/com/fr/plugin/db/redis/help/client/RedisV8Client.java new file mode 100644 index 0000000..388ebbb --- /dev/null +++ b/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 { + + 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 set = jedis.keys(key); + FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); + return V8ObjectUtils.toV8Array(v8, new ArrayList(set)); + } + + @Override + @ScriptBridge + public V8Array hmget(String key, String... fields) { + long start = System.currentTimeMillis(); + List 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 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 set = jedis.keys(pattern); + FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); + return V8ObjectUtils.toV8Array(v8, new ArrayList(set)); + } + + @Override + @ScriptBridge + public V8Array lrange(String key, long start, long end) { + long start0 = System.currentTimeMillis(); + List 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 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 set = jedis.smembers(key); + FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); + return V8ObjectUtils.toV8Array(v8, new ArrayList(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> data = new ArrayList>(); + for (int i = 0; i < realCount; i++) { + V8Array v8Row = v8Table.getArray(i); + List row = new ArrayList(); + 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; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/help/client/SimpleDataModel.java b/src/main/java/com/fr/plugin/db/redis/help/client/SimpleDataModel.java new file mode 100644 index 0000000..c8f1046 --- /dev/null +++ b/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> data = new ArrayList>(); + private String[] columnNames = null; + + SimpleDataModel(String[] columnNames, List> 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> getData() { + return data; + } + + public void setData(List> data) { + this.data = data; + } + + public String[] getColumnNames() { + return columnNames; + } + + public void setColumnNames(String[] columnNames) { + this.columnNames = columnNames; + } +} diff --git a/src/main/java/com/fr/plugin/db/redis/util/RedisUtils.java b/src/main/java/com/fr/plugin/db/redis/util/RedisUtils.java index 0c13538..3ce98bb 100644 --- a/src/main/java/com/fr/plugin/db/redis/util/RedisUtils.java +++ b/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.fr.base.Parameter; import com.fr.base.TemplateUtils; +import com.fr.plugin.db.redis.help.ScriptBridge; import com.fr.stable.ArrayUtils; import com.fr.third.redis.clients.jedis.Jedis; @@ -41,9 +42,11 @@ public class RedisUtils { } public static void registerJavaMethods(V8Object v8Object, Object target) { - Method[] methods = target.getClass().getDeclaredMethods(); + Method[] methods = target.getClass().getMethods(); 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()); + } } } }