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; } }